package jpave.manager;

/**************************************************
 * This file contains the following (in this order)
 * 1 XXX Creates the main window
 * 2 XXX Panels that make up main window
 * 3 XXX routine for main window
 * 4 XXX Panels that replace main window (Assembly Options, Annotation Options, Annotation Add/Edit)
 * 5 XXX routines to transfer information to the Manager data
 *  		other panels are in their own files
 * 6 XXX Database routines - each routine creates its own connection
 * 7 XXX other assorted routines and classes
 */
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Collections;
import java.util.Iterator;
import java.util.Vector;
import java.util.prefs.Preferences;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import assem.DBConn;
import util.Debug.ErrorReport;
import util.methods.BlastArgs;
import util.methods.HostsCfg;
import util.methods.PaveProps;
import util.methods.PropType;
import util.methods.UIHelpers;
import util.ui.ButtonComboBox;
import util.ui.UserPrompt;
import jpave.annotator.CoreMain;
import jpave.manager.ManagerData;
import jpave.database.CoreDBWrapper;
import jpave.database.OverviewDBWrapper;

public class ManagerFrame extends JFrame {
	private static final long serialVersionUID = 7879962219972222820L;
	
	private static final String MAX_MEM = "2048"; // used to launch all programs except assembly
	public static final String LIBDIR = "libraries/"; // these directories are hardcoded in many places
	public static final String PROJDIR = "projects/";
	public static final String ANNODIR = "projects/DBfasta";
	
	public static final String LIBCNT =  "L__";
	public static final String LIBRPKM = "LN__";
	public static final String PVALUE =  "P_"; // note just one _ 
	
	// also defined in cmp.main.Globals
	public static final Color BGCOLOR = Color.WHITE;
	public static final Color FUNCTIONCOLOR = new Color(215, 229, 243); // replace with no color
	public static final Color MENUCOLOR = new Color(229, 245, 237);	// beige
	public static final Color HELPCOLOR = new Color(245, 213, 234);	// rose
	public static final Color PROMPTCOLOR = new Color(243, 235, 227);	// light beige
	public static final Color LAUNCHCOLOR = new Color(200, 200, 240); // light purple
	
	public static final int FRAME_MODE_MAIN = 0;
	public static final int FRAME_MODE_ASSEM = 1;
	public static final int FRAME_MODE_ANNO = 2;
	public static final int FRAME_MODE_TRANS_LIB_EDIT = 3;
	public static final int FRAME_MODE_EXP_LIB_EDIT = 4;
	public static final int FRAME_MODE_ANNO_DB_EDIT = 5;
	
	private static final int TABLE_WIDTH = 400;
	private static final int COLUMN_LABEL_WIDTH = 90;
	private static final int TEXTFIELD_WIDTH = 15;
	private static final int BLAST_ARGS_TEXTFIELD_WIDTH = 30;
	private static final int NUM_FIELD_WIDTH = 5;
	
	private static final String [] THREE_INT_VALS = { "Minimal Overlap", "Minimal % Identity", "Maximal Overhang" };
	
	public HostsCfg hostsObj;
	
	public ManagerFrame() {
		hostsObj = new HostsCfg();
		BlastArgs.availSearch();
		
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent we) {
				try {
					if(nFrameMode == FRAME_MODE_MAIN) {
						//Need to test if application is running
						if(!btnExecLoadLib.isEnabled() && cmbProjects.getSelectedIndex() > 0) {
							if(JOptionPane.showConfirmDialog(getInstance(), "There is a subprocess currently running. Exiting will terminate the subprocess", "", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION)
								System.exit(0);
							else
								return;
						}
						Preferences userPrefs = Preferences.userRoot();
						userPrefs.putInt("manager_pave_frame_win_x", getX());
						userPrefs.putInt("manager_pave_frame_win_y", getY());
						userPrefs.putInt("manager_pave_frame_win_width", getWidth());
						userPrefs.putInt("manager_pave_frame_win_height", getHeight());
						userPrefs.flush();
	
						System.exit(0);
					}
					else if(nFrameMode == FRAME_MODE_ASSEM) {
						pnlAssemblyOptions.setVisible(false);
						mainPanel.setVisible(true);
					}
					else if(nFrameMode == FRAME_MODE_ANNO) {
						pnlAnnoDBOptions.setVisible(false);
						mainPanel.setVisible(true);
					}
					else if(nFrameMode == FRAME_MODE_TRANS_LIB_EDIT) {
						pnlTransLibEdit.setVisible(false); 
						mainPanel.setVisible(true);
					}
					else if(nFrameMode == FRAME_MODE_EXP_LIB_EDIT) {
						if(bRemoveExpLibOnDiscard) {
							curManData.removeExpLib(nCurrentExpLibIndex);
							updateUI();
						}
						pnlExpLibEdit.setVisible(false);
						mainPanel.setVisible(true);
					}
					else if(nFrameMode == FRAME_MODE_ANNO_DB_EDIT) {
						if(bRemoveAnnoOnDiscard) {
							curManData.setAnnoDBAt(nCurrentAnnoIndex, null);
							updateUI();
						}
						
						pnlAnnoDBEdit.setVisible(false);
						mainPanel.setVisible(true);
					}
					nFrameMode = FRAME_MODE_MAIN;
				}
				catch(Exception e) {
					ErrorReport.prtReport(e, "Error loading preferences");
				}
			}
		});
		try {
			setTitle("runSingleTCW on " + InetAddress.getLocalHost().getHostName());
		}
		catch(Exception e) {setTitle("runSingleTCW");}
		
		new HostsCfg();
		createPanel();
		setWindowSettings();
	}
	
	private void setWindowSettings() {
		Preferences userPrefs = Preferences.userRoot();
		int nX = userPrefs.getInt("manager_pave_frame_win_x", Integer.MAX_VALUE);
		int nY = userPrefs.getInt("manager_pave_frame_win_y", Integer.MAX_VALUE);
		int nWidth = userPrefs.getInt("manager_pave_frame_win_width", Integer.MAX_VALUE);
		int nHeight = userPrefs.getInt("manager_pave_frame_win_height", Integer.MAX_VALUE);
		if (nX == Integer.MAX_VALUE) {
			UIHelpers.centerScreen(this);
		} else {
			setBounds(nX, nY, nWidth, nHeight);
		}
	}
		
	/**************************************************
	 * XXX Creates the main window
	 */
	private void createPanel() {
		createFirstTwoRowPanel(getLibraryList(true));
		createSecondTwoRowPanel();		
		
		createTransLibPanel();		 
		createExpLibPanel();
		createAnnoDBPanel();
		
		pnlAnnoDBEdit = new EditAnnoPanel(this); 
		pnlTransLibEdit = new EditTransLibPanel(this);
		pnlExpLibEdit = EditPanel.createExpLibEditPanel(this);
		pnlExpLibEdit.setVisible(false);
		pnlGenReps = new GenRepsPanel(this);
		pnlRemark = new AddRemarkPanel(this);
		pnlRemark.setVisible(false);
		createAnnoDBOptionPanel();
		createAssemblyOptionPanel();
		
		JPanel outsidePanel = new JPanel();
		outsidePanel.setLayout(new BoxLayout(outsidePanel, BoxLayout.PAGE_AXIS));
		outsidePanel.setBackground(BGCOLOR);
		outsidePanel.setAlignmentX(Component.LEFT_ALIGNMENT);

		mainPanel = new JPanel();
		mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
		mainPanel.setBackground(BGCOLOR);
		mainPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
		mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
				
		mainPanel.add(pnlProject);

		mainPanel.add(Box.createVerticalStrut(15));
		mainPanel.add(pnlGeneral);

		mainPanel.add(new JSeparator());
		mainPanel.add(Box.createVerticalStrut(10));
		mainPanel.add(new JLabel("1. LOAD LIBRARIES"));
		mainPanel.add(Box.createVerticalStrut(5));
		mainPanel.add(new JLabel("Sequence Libraries"));
		mainPanel.add(Box.createVerticalStrut(5));
		mainPanel.add(pnlTransLib);

		mainPanel.add(Box.createVerticalStrut(15));
		mainPanel.add(new JLabel("Associated Count Libraries"));
		mainPanel.add(Box.createVerticalStrut(5));
		mainPanel.add(pnlExpLib);
				
		// this is place holder for Transcript read count table
		// which gets populated in the updateUI method
		JPanel tempRow = new JPanel();
		tempRow.setBackground(BGCOLOR);
		tempRow.setAlignmentX(Component.LEFT_ALIGNMENT);
		tempRow.setLayout(new BoxLayout(tempRow, BoxLayout.LINE_AXIS));
		
		btnExecLoadLib = new JButton("Load Libraries");
		btnExecLoadLib.setAlignmentX(Component.RIGHT_ALIGNMENT);
		btnExecLoadLib.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Thread buildThread = new Thread(new Runnable() {
					public void run() {
						actionLoadLibrary();
					}
				});
				buildThread.setPriority(Thread.MIN_PRIORITY);
				buildThread.start();
			}
		});
		mainPanel.add(Box.createVerticalStrut(10));
		tempRow.add(btnExecLoadLib);
		mainPanel.add(tempRow);
		
		mainPanel.add(Box.createVerticalStrut(15));
		mainPanel.add(new JSeparator());
		mainPanel.add(Box.createVerticalStrut(10));
		mainPanel.add(new JLabel("2. RUN INSTANTIATE (or assemble)"));
		mainPanel.add(Box.createVerticalStrut(10));
		
		tempRow = getPanel(true);
		tempRow.add(chkSkipAssembly);
		tempRow.add(Box.createHorizontalStrut(15));
		tempRow.add(chkUseTransName);
		mainPanel.add(tempRow);
		mainPanel.add(Box.createVerticalStrut(5));
		
		btnAssemOptions = new JButton("Options");
		btnAssemOptions.setBackground(MENUCOLOR);
		btnAssemOptions.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				actionOptionsTrans();
			}
		});
		
		tempRow = new JPanel();
		tempRow.setAlignmentX(Component.LEFT_ALIGNMENT);
		tempRow.setLayout(new BoxLayout(tempRow, BoxLayout.LINE_AXIS));
		tempRow.setBackground(BGCOLOR);
		
		btnExecAssem = new JButton("Instantiate");
		btnExecAssem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Thread buildThread = new Thread(new Runnable() {
					public void run() {
						actionCreateTrans();
					}
				});
				buildThread.setPriority(Thread.MIN_PRIORITY);
				buildThread.start();					
			}
		});
		
		tempRow.add(btnAssemOptions);
		tempRow.add(Box.createHorizontalStrut(10));
		tempRow.add(btnExecAssem);
		
		mainPanel.add(tempRow);

		mainPanel.add(Box.createVerticalStrut(10));
		mainPanel.add(new JSeparator());

		btnEditAnnoOptions = new JButton("Options");
		btnEditAnnoOptions.setBackground(MENUCOLOR);
		btnEditAnnoOptions.setAlignmentX(Component.LEFT_ALIGNMENT);
		btnEditAnnoOptions.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				actionOptionsAnno();
			}
		});
		
		btnImportAnnot = new JButton("Import AnnoDBs");
		btnImportAnnot.setBackground(PROMPTCOLOR);
		btnImportAnnot.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					JFileChooser fc = new JFileChooser();
					fc.setCurrentDirectory(getProjPath());

					if(fc.showOpenDialog(getInstance()) == JFileChooser.APPROVE_OPTION) {
						ManagerData.importAnnoDBs(fc.getSelectedFile(), curManData);
					}
					updateUI();
				}
				catch(Exception err) {
					ErrorReport.reportError(err, "Error running annotation");
				}
			}
		});
		
		btnExecAnno = new JButton("Annotate Sequences");
		btnExecAnno.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Thread buildThread = new Thread(new Runnable() {
					public void run() {
						actionAnno();
					}
				});
				buildThread.setPriority(Thread.MIN_PRIORITY);
				buildThread.start();
			}
		});
		
		btnRunViewPAVE = new JButton("Launch viewSingleTCW");
		btnRunViewPAVE.setBackground(LAUNCHCOLOR);
		btnRunViewPAVE.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				Thread buildThread = new Thread(new Runnable() {
					public void run() {
						actionView();	
					}
				});
				buildThread.setPriority(Thread.MIN_PRIORITY);
				buildThread.start();
			}
		});

		btnRunDE = new JButton("Launch DE");
		btnRunDE.setBackground(LAUNCHCOLOR);
		btnRunDE.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				Thread buildThread = new Thread(new Runnable() {
					public void run() {
						actionDE();
					}
				});
				buildThread.setPriority(Thread.MIN_PRIORITY);
				buildThread.start();
			}
		});
		
		btnAddRemark = new JButton("Add Remarks or Locations");
		btnAddRemark.setBackground(MENUCOLOR);
		btnAddRemark.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				pnlRemark.setStartingDir(getLibPath());
				pnlRemark.reset();
				
				pnlRemark.setVisible(true);
				mainPanel.setVisible(false);
			}
		});

		btnUpdateGO = new JButton("Update GO");
		btnUpdateGO.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent arg0) 
			{
				Thread buildThread = new Thread(new Runnable() 
				{
					public void run() 
					{
						actionGO();
					}
				});
				buildThread.setPriority(Thread.MIN_PRIORITY);
				buildThread.start();
			}
		});
		
		lblGODB = new JLabel("");
		
		mainPanel.add(Box.createVerticalStrut(10));
		mainPanel.add(new JLabel("3. RUN ANNOTATION"));
		mainPanel.add(Box.createVerticalStrut(5));
		mainPanel.add(new JLabel("AnnoDBs (e.g. UniProt)"));
		mainPanel.add(Box.createVerticalStrut(5));
		
		tempRow = new JPanel();
		tempRow.setAlignmentX(Component.LEFT_ALIGNMENT);
		tempRow.setLayout(new BoxLayout(tempRow, BoxLayout.LINE_AXIS));
		tempRow.setBackground(BGCOLOR);
		
		tempRow.add(btnEditAnnoOptions);
		tempRow.add(Box.createHorizontalStrut(5));
		tempRow.add(btnImportAnnot);
		tempRow.add(Box.createHorizontalStrut(10));
		tempRow.add(btnExecAnno);
		tempRow.add(Box.createHorizontalStrut(5));
		tempRow.add(btnUpdateGO);
		
		mainPanel.add(pnlAnnoDB);
		mainPanel.add(Box.createVerticalStrut(5));
		mainPanel.add(tempRow);
				
		tempRow = new JPanel();
		tempRow.setAlignmentX(Component.LEFT_ALIGNMENT);
		tempRow.setLayout(new BoxLayout(tempRow, BoxLayout.LINE_AXIS));
		tempRow.setBackground(BGCOLOR);
		tempRow.add(lblGODB);
		mainPanel.add(Box.createVerticalStrut(5));
		mainPanel.add(tempRow);
		
		Dimension d = mainPanel.getPreferredSize();
		d.height = pnlProject.getPreferredSize().height;
		
		pnlProject.setMinimumSize(d);
		pnlProject.setPreferredSize(d);
		pnlProject.setMaximumSize(d);
		
		outsidePanel.add(mainPanel);
		outsidePanel.add(pnlAnnoDBEdit);
		outsidePanel.add(pnlTransLibEdit);
		outsidePanel.add(pnlExpLibEdit);
		outsidePanel.add(pnlAssemblyOptions);
		outsidePanel.add(pnlAnnoDBOptions);
		outsidePanel.add(pnlGenReps);
		outsidePanel.add(pnlRemark);

		tempRow = new JPanel();
		tempRow.setAlignmentX(Component.LEFT_ALIGNMENT);
		tempRow.setLayout(new BoxLayout(tempRow, BoxLayout.LINE_AXIS));
		tempRow.setBackground(BGCOLOR);

		tempRow.add(btnRunViewPAVE);
		tempRow.add(Box.createHorizontalStrut(5));
		tempRow.add(btnRunDE);
		tempRow.add(Box.createHorizontalStrut(5));
		tempRow.add(btnAddRemark);
		
		mainPanel.add(Box.createVerticalStrut(10));
		mainPanel.add(tempRow);
		
		sPane = new JScrollPane(outsidePanel);
		getContentPane().add(sPane);
		
		pack();
		updateUI();
	}
	/**************************************************************
	 * XXX Panels that make up main window
	 */
	private void createFirstTwoRowPanel(String [] projectNames) {
		pnlProject = new JPanel();
		pnlProject.setLayout(new BoxLayout(pnlProject, BoxLayout.PAGE_AXIS));
		pnlProject.setBackground(BGCOLOR);
		pnlProject.setAlignmentX(Component.LEFT_ALIGNMENT);
		
		btnAddProject = new JButton("Add Project");
		btnAddProject.setBackground(PROMPTCOLOR);
		btnAddProject.setAlignmentX(Component.RIGHT_ALIGNMENT);
		btnAddProject.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				boolean done = true;
				String result = null;
				do {
					result = (String)JOptionPane.showInputDialog(getInstance(), "Enter name for new project", "", JOptionPane.PLAIN_MESSAGE);
					if(result != null && isFilenameValid(result) && result.matches("[A-Za-z_0-9]+")) {
						cmbProjects.addItem(result);
						curManData = ManagerData.createNewProject(result);
						cmbProjects.setSelectedItem(result);
						updateUI();
						saveProject();
					}
					
					if(result != null && (!isFilenameValid(result) || !result.matches("[A-Za-z_0-9]+"))) {
						JOptionPane.showMessageDialog(getInstance(), "Invalid ID. \n\nThe id may only contain letters, '_' or digits", "Error - invalid ID", JOptionPane.PLAIN_MESSAGE);
						done = false;
					}
				} while(!done && result !=null);
				chkSkipAssembly.setSelected(true);
			}
		});

		btnHelp = new JButton("Help");
		btnHelp.setBackground(HELPCOLOR);
		btnHelp.setAlignmentX(Component.RIGHT_ALIGNMENT);
		btnHelp.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				UserPrompt.displayHTMLResourceHelp(getInstance(), "runSingleTCW", "html/runSingleTCW/ManagerHelp.html");
			}
		});
		// second line
		cmbProjects = new ButtonComboBox();
		cmbProjects.setBackground(BGCOLOR);
		refreshProjectList();
		
		cmbProjects.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(cmbProjects.getSelectedIndex() > 0) {
					ManagerData.validateProjectFiles((String)cmbProjects.getSelectedItem());
					curManData = ManagerData.readLIBcfg_sTCWcfg(
							hostsObj, (String)cmbProjects.getSelectedItem());
					if (curManData==null) ErrorReport.die("TCW error: remove LIB.cfg and start again");
					
					curManData.setLibraryLoaded(isDBLoaded());
					curManData.setProteinDB(isProteinDBLoaded());
					String param = curManData.getDefaultAnnoDBBlastParams();
					if(param != null && param.length() > 0) {
						BlastArgs.setBlastxOptions(param);
					}
					
					pnlTransLibEdit.clearCountFileList();
					for(int x=0; x<curManData.getNumCountFiles(); x++) {
						pnlTransLibEdit.addCountFile(curManData.getCountFileAt(x), curManData.getCountHeaderAt(x));
					}
					updateAnnoDBLoadStatus();
				}
				else {
					curManData = null;
				}
				updateUI();
			}
		});
		cmbProjects.setMaximumSize(cmbProjects.getPreferredSize());
		
		btnRemoveProject = new JButton("Remove...");
		btnRemoveProject.setBackground(PROMPTCOLOR);
		btnRemoveProject.setAlignmentX(Component.RIGHT_ALIGNMENT);
		
		final JPopupMenu popup = new JPopupMenu();
		popup.add(new JMenuItem(new AbstractAction("Remove annotation") {
			private static final long serialVersionUID = 4692812516440639008L;
			public void actionPerformed(ActionEvent e) {
				int ret = JOptionPane.showOptionDialog(null, "Confirm: remove annotation",
						"runSingleTCW", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
				if (ret == JOptionPane.YES_OPTION)
				{
					System.err.println("Removing annotation...");
					removeSelectedAnnotation();
					curManData.clearAnnoDBload();
					updateUI();
				}
			}
		}));
		popup.add(new JMenuItem(new AbstractAction("Remove SQL database") {
			private static final long serialVersionUID = 4692812516440639008L;
			public void actionPerformed(ActionEvent e) {
				int ret = JOptionPane.showOptionDialog(null, "Confirm: remove SQL database",
						"runSingleTCW", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
				if (ret == JOptionPane.YES_OPTION)
				{
					System.err.println("Removing SQL database...");
					removeSelectedDatabase();
					updateUI();
				}
			}
		}));
		
		popup.add(new JMenuItem(new AbstractAction("Remove project files from disk") {
			private static final long serialVersionUID = 4692812516440639008L;
			public void actionPerformed(ActionEvent e) {
				int ret = JOptionPane.showOptionDialog(null, "Confirm: remove project files",
						"runSingleTCW", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
				if (ret == JOptionPane.YES_OPTION)
				{
					System.err.println("Removing project files ...");
					removeSelectedProject();
				}
			}
		}));
		btnRemoveProject.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                popup.show(e.getComponent(), e.getX(), e.getY());
            }
        });
		
		btnSaveProject = new JButton("Save");
		btnSaveProject.setBackground(BGCOLOR);
		btnSaveProject.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				saveProject();
			}
		});
		
		btnGetAllState = new JButton("View All Overviews");
		btnGetAllState.setBackground(LAUNCHCOLOR);
		btnGetAllState.setAlignmentX(Component.LEFT_ALIGNMENT);
		btnGetAllState.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				try {
					Class.forName("com.mysql.jdbc.Driver");
					String [] lines = new String[cmbProjects.getItemCount()+2];
					lines[0] = "States for /project databases";
					lines[1] = "";
					lines[2] = String.format("%-20s%-20s%-20s%-10s%-15s%-15s", "Project", "Database", "ID", "#Libs", "Assembly", "Annotation");
					for(int x=1; x<cmbProjects.getItemCount(); x++) {
						ManagerData tempProj = ManagerData.readsTCWcfg((String)cmbProjects.getItemAt(x));
						if (tempProj==null) return;
						
						String projName = tempProj.getProjectName();
						String database = tempProj.getPAVEDB();
						String id = tempProj.getAssemblyID();
						int numLibs = 0;
						String assemDate = null;
						String annoDate = null;

						if(checkMysqlDB(hostsObj.host, tempProj.getPAVEDB(), hostsObj.user, hostsObj.pass)) {
							String dbstr = hostsObj.getJdbcStr(tempProj.getPAVEDB());
							Connection con = null; 
			
							con = DriverManager.getConnection(dbstr, hostsObj.user, hostsObj.pass);
							Statement st = con.createStatement();
							
							ResultSet rset = st.executeQuery("SELECT assemblydate, annotationdate FROM assembly");
							if(rset.first()) {
								assemDate = rset.getString(1);
								annoDate = rset.getString(2);
							}
							rset.close();
							
							rset = st.executeQuery("SELECT COUNT(*) FROM library");
							if(rset.first())
								numLibs = rset.getInt(1);
							rset.close();
						}
						
						lines[x+2] = String.format("%-20s%-20s%-20s%-10d%-15s%-15s", projName, database, id, numLibs, assemDate, annoDate);
					}
					UserPrompt.displayInfoMonoSpace(getInstance(), "States", lines, true, false);
				}
				catch(Exception e) {
					ErrorReport.prtReport(e, "Error getting all states");
				}
			}
		});
		
		btnGetState = new JButton("Overview");
		btnGetState.setBackground(LAUNCHCOLOR);
		btnGetState.setAlignmentX(Component.LEFT_ALIGNMENT);
		btnGetState.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				try {
					String val = null;
					
					if(!checkMysqlDB(hostsObj.host, curManData.getPAVEDB(),hostsObj.user, hostsObj.pass)) {
						val = "Database does not exist";
						UserPrompt.displayInfoMonoSpace(getInstance(), "Overview for " + 
								curManData.getProjectName(), val.split("\n"), false, true);
						return;
					}
					
					DBConn conn = hostsObj.getDBConn(curManData.getPAVEDB());
					ResultSet rs = conn.executeQuery("SELECT pja_msg FROM assem_msg");
						
					if(rs.first()) {
						val = rs.getString(1);
						if (val==null || (val != null && val.length() <= 10)) {
							OverviewDBWrapper ov = new OverviewDBWrapper(conn.getDBconn());
							Vector <String> lines = new Vector <String> ();
							val = ov.createOverview(lines);
						}
					}
					rs.close();
					if (val==null && conn.executeCount("select count(*) from library")>0) {
						val = "Libraries:\n";
						val += String.format("%10s %8s %10s   %s\n", "LibID", "Size", "Trans", "Info");
						rs = conn.executeQuery("Select libid, libsize, parent, fastafile, reps from library");
						while (rs.next()) {
							String trans = rs.getString(3);
							if (trans.equals("")) trans = "N/A";
							String file = rs.getString(4);
							String reps = rs.getString(5);
							String info = (file.equals("")) ? reps : file;
							val += String.format("%10s %8d %10s   %s\n", 
									rs.getString(1), rs.getInt(2), trans, info);
						}
					}
					if (val==null) val = "Empty database -- delete and restart.";
					
					UserPrompt.displayInfoMonoSpace(getInstance(), "Overview for " + 
							curManData.getProjectName(), val.split("\n"), false, true);
				}
				catch(Exception e) {
					ErrorReport.prtReport(e, "Error getting project overview");
				}
			}
		});
		
		JPanel tempRow = new JPanel();
		tempRow.setLayout(new BoxLayout(tempRow, BoxLayout.LINE_AXIS));
		tempRow.setAlignmentX(Component.LEFT_ALIGNMENT);
		tempRow.setBackground(BGCOLOR);
		
		// does not seem to work
		// tempRow.add(btnGetAllState);
		// tempRow.add(Box.createHorizontalStrut(10));
		tempRow.add(btnAddProject);
		tempRow.add(Box.createHorizontalStrut(10));
		tempRow.add(btnHelp);
		
		pnlProject.add(tempRow);
		pnlProject.add(Box.createVerticalStrut(10));
		
		tempRow = new JPanel();
		tempRow.setLayout(new BoxLayout(tempRow, BoxLayout.LINE_AXIS));
		tempRow.setAlignmentX(Component.LEFT_ALIGNMENT);
		tempRow.setBackground(BGCOLOR);
		
		tempRow.add(new JLabel("Project"));
		tempRow.add(Box.createHorizontalStrut(5));
		tempRow.add(cmbProjects);
		tempRow.add(Box.createHorizontalStrut(10));
		tempRow.add(btnSaveProject);
		tempRow.add(Box.createHorizontalStrut(10));
		tempRow.add(btnRemoveProject);
		tempRow.add(Box.createHorizontalStrut(10));
		tempRow.add(btnGetState);
		
		pnlProject.add(tempRow);
	}
	/****************************************************************
	 * Two two rows with Host/CPU/singleTCW /Database
	 */
	private void createSecondTwoRowPanel() {
		theHosts = new Vector<String>(); 
		theHosts.add(hostsObj.host());
		
		pnlGeneral = new JPanel();
		pnlGeneral.setLayout(new BoxLayout(pnlGeneral, BoxLayout.LINE_AXIS));
		pnlGeneral.setBackground(BGCOLOR);
		pnlGeneral.setAlignmentX(Component.LEFT_ALIGNMENT);
	
		JPanel leftPanel = new JPanel();
		leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS));
		leftPanel.setBackground(BGCOLOR);
		leftPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
		leftPanel.setAlignmentY(Component.TOP_ALIGNMENT);
		
		cmbHost = new ButtonComboBox();
		cmbHost.setBackground(BGCOLOR);
		cmbHost.addItem("localhost");

		Iterator<String> nameIter = theHosts.iterator();
		while(nameIter.hasNext()) {
			String hostname = nameIter.next();
			if(!hostname.equals("localhost"))
				cmbHost.addItem(hostname);
		}
		cmbHost.setMaximumSize(cmbHost.getPreferredSize());
		cmbHost.setMinimumSize(cmbHost.getPreferredSize());
		
		leftPanel.add(new JLabel("Host: " + hostsObj.host));
		leftPanel.add(Box.createVerticalStrut(5));

		txtAssemblyID = new JTextField(TEXTFIELD_WIDTH);
		txtAssemblyID.setMaximumSize(txtAssemblyID.getPreferredSize());
		txtAssemblyID.setMinimumSize(txtAssemblyID.getPreferredSize());
		txtAssemblyID.addCaretListener(new CaretListener() {
			public void caretUpdate(CaretEvent arg0) {
				if(curManData != null)
					curManData.setAssemblyID(txtAssemblyID.getText());
			}
		});
		leftPanel.add(addRow("singleTCW ID", txtAssemblyID));
		leftPanel.add(Box.createVerticalStrut(5));
		
		JPanel rightPanel = new JPanel();
		rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.PAGE_AXIS));
		rightPanel.setBackground(BGCOLOR);
		rightPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
		rightPanel.setAlignmentY(Component.TOP_ALIGNMENT);
		
		txtNumCPUs = new JTextField(NUM_FIELD_WIDTH);
		txtNumCPUs.setMaximumSize(txtNumCPUs.getPreferredSize());
		txtNumCPUs.setMinimumSize(txtNumCPUs.getPreferredSize());
		txtNumCPUs.addCaretListener(new CaretListener() {
			public void caretUpdate(CaretEvent e) {
				try {
					curManData.setNumCPUs(Integer.parseInt(txtNumCPUs.getText()));
				} catch(Exception err) {}
			}
		});
		rightPanel.add(addRow("# CPUs", txtNumCPUs));
		rightPanel.add(Box.createVerticalStrut(5));
		
		txtPAVEdb = new JTextField(TEXTFIELD_WIDTH);
		txtPAVEdb.setMaximumSize(txtPAVEdb.getPreferredSize());
		txtPAVEdb.setMinimumSize(txtPAVEdb.getPreferredSize());
		txtPAVEdb.addCaretListener(new CaretListener() {
			public void caretUpdate(CaretEvent e) {
				if(curManData != null)
					curManData.setPAVEDB(txtPAVEdb.getText());
			}
		});
		rightPanel.add(addRow("Database", txtPAVEdb));
		rightPanel.add(Box.createVerticalStrut(5));
		
		pnlGeneral.add(leftPanel);
		pnlGeneral.add(Box.createHorizontalStrut(30));
		pnlGeneral.add(rightPanel);		
		pnlGeneral.setMaximumSize(pnlGeneral.getPreferredSize());
	}
	/*******************************************************************
	 * XXX Utilities
	 */
	// called by EditAnnoPanel and GenRepsPanel
	public static JPanel getPanel(boolean forRow) {
		JPanel retVal = new JPanel();
		if(forRow)
			retVal.setLayout(new BoxLayout(retVal, BoxLayout.LINE_AXIS));
		else
			retVal.setLayout(new BoxLayout(retVal, BoxLayout.PAGE_AXIS));
		retVal.setAlignmentX(Component.LEFT_ALIGNMENT);
		retVal.setBackground(BGCOLOR);
		return retVal;
	}
	
	public void setMainPanelVisible(boolean visible) {
		mainPanel.setVisible(visible);
	}
	public File getLibPath() {
		return new File(LIBDIR + curManData.getProjectName());
	}
	public File getProjPath() {
		return new File(PROJDIR + curManData.getProjectName());
	}
	public File getAnnoDBPath() {
		return new File(ANNODIR);
	}
	public void setFrameMode(int mode) { nFrameMode = mode; }
	
	private static JPanel addRow(String fieldName, JComponent theField) {
		JPanel retVal = new JPanel();
		retVal.setLayout(new BoxLayout(retVal, BoxLayout.LINE_AXIS));
		retVal.setBackground(BGCOLOR);
		retVal.setAlignmentX(Component.LEFT_ALIGNMENT);
		
		JLabel theLabel = new JLabel(fieldName);
		int diff = COLUMN_LABEL_WIDTH - theLabel.getPreferredSize().width;
		
		retVal.add(theLabel);
		retVal.add(Box.createHorizontalStrut(diff));
		retVal.add(theField);
		
		retVal.setMaximumSize(retVal.getPreferredSize());
		
		return retVal;
	}
	// used by annoDBOptionPanel and assemblyOptionPanel
	private JPanel createRowPanel() {
		JPanel row = new JPanel();
		row.setLayout(new BoxLayout(row, BoxLayout.LINE_AXIS));
		row.setBackground(BGCOLOR);
		row.setAlignmentX(Component.LEFT_ALIGNMENT);

		return row;
	}
	/******************************************************
	 * XXX ACTIONS - call external programs
	 */
	private void actionLoadLibrary() {
		try {
			if (!saveProject()) return;

			bBusy = true;
			updateUI();

			final String JAR_DIR = "java/jars";
			final String JAR = JAR_DIR + "/stcw.jar";
			final String MAXMEM = MAX_MEM;
			
			final String classPath = JAR + ":" + JAR_DIR + "/mysql-connector-java-5.0.5-bin.jar";
			final String cmd = "java -Xmx" + MAXMEM + "m -cp " + classPath + " assem.LoadLibMain " + curManData.getProjectName();

			Process pr = Runtime.getRuntime().exec(cmd);
			
			pr.getOutputStream().flush();
			OutputHandler oh = new OutputHandler(pr.getErrorStream());
			InputHandler ih = new InputHandler(pr.getOutputStream());
			
			oh.start();
			ih.start();
			pr.waitFor();
			oh.Stop();
			ih.Stop();
			
			DBConn conn = hostsObj.getDBConn(curManData.getPAVEDB());
			int c = conn.executeCount("select count(*) from assem_msg");
			if (c==0) { // CAS 12/21/14
				JOptionPane.showMessageDialog(null, "Load Library failed", "Error", 
						JOptionPane.PLAIN_MESSAGE);
			}
			else {
				curManData.setProteinDB(isProteinDBLoaded());
				curManData.setLibraryLoaded(true);
			}
			
			bBusy = false;
			dbExists=isDBLoaded();
			updateUI();	
			
		} catch (Exception e) {ErrorReport.prtReport(e, "Error launching Load Library");}
	}
	private void actionCreateTrans() {
		try {
			if (!saveProject()) return;
		
			bBusy = true;
			updateUI();

			int maxMem = 0;
			int numClones = 0;
			int avgLen = 0;

			try
			{
				DBConn conn = hostsObj.getDBConn(curManData.getPAVEDB());
				ResultSet rset = conn.executeQuery("select count(*) from clone");
				rset.next();
				numClones = rset.getInt(1);
				rset.close();
				
				rset = conn.executeQuery("select sum(libsize*avglen)/sum(libsize) from library"); 
				rset.next();
				avgLen = rset.getInt(1);
				rset.close();
				
				maxMem = numClones/200;
				if(avgLen > 300) {
					maxMem *= (avgLen/300);
				}
				
				maxMem += 1000;
				if(numClones > 3000000) {
					System.err.println("*Warning: " + numClones + " EST found in databse. Estimated memory requirement: " + maxMem + "M");
					System.err.println("*See System Guide for more information on memory usage.");
				}
				
			} 
			catch (Exception e)
			{
				System.err.println("Can't locate database " + curManData.getPAVEDB() + " on host " + hostsObj.host);
				System.exit(0);
			}

			final String JAR_DIR = "java/jars";
			final String JAR = JAR_DIR + "/stcw.jar";
			
			final String classPath = JAR;
			final String cmd = "java -Xmx" + maxMem + "m -cp " + classPath + " assem.AssemMain " + curManData.getProjectName();

			Process pr = Runtime.getRuntime().exec(cmd);
			pr.getOutputStream().flush();
			OutputHandler oh = new OutputHandler(pr.getErrorStream());
			InputHandler ih = new InputHandler(pr.getOutputStream());
			
			oh.start();
			ih.start();
			pr.waitFor();
			oh.Stop();
			ih.Stop();
								
			bBusy = false;
			updateUI();
		} catch (Exception e) {
			ErrorReport.prtReport(e, "Error generating list");
		}
	}
	private void actionOptionsTrans() {
		try {
			PaveProps theProps = new PaveProps(PropType.Assem);

			if(curManData.getClique().length() > 0)
				pnlClique.setValue(curManData.getClique());
			else
				pnlClique.setValue(theProps.getProperty("CLIQUE"));
			
			if(curManData.getCliqueBlastEval().length() > 0)
				txtCliqueBlastEval.setText(curManData.getCliqueBlastEval());
			else
				txtCliqueBlastEval.setText(theProps.getProperty("CLIQUE_BLAST_EVAL"));
			
			if(curManData.getCliqueBlastParam().length() > 0)
				txtCliqueBlastParams.setText(curManData.getCliqueBlastParam());
			else
				txtCliqueBlastParams.setText(theProps.getProperty("CLIQUE_BLAST_PARAMS"));

			if(curManData.getSelfJoin().length() > 0)
				pnlSelfJoin.setValue(curManData.getSelfJoin());
			else
				pnlSelfJoin.setValue(theProps.getProperty("SELF_JOIN"));
			
			if(curManData.getBuryBlastEval().length() > 0)
				txtBuryBlastEval.setText(curManData.getBuryBlastEval());
			else
				txtBuryBlastEval.setText(theProps.getProperty("BURY_BLAST_EVAL"));

			if(curManData.getBuryBlastIdentity().length() > 0)
				txtBuryBlastIdentity.setText(curManData.getBuryBlastIdentity());
			else
				txtBuryBlastIdentity.setText(theProps.getProperty("BURY_BLAST_IDENTITY"));

			if(curManData.getBuryBlastParams().length() > 0)
				txtBuryBlastParams.setText(curManData.getBuryBlastParams());
			else
				txtBuryBlastParams.setText(theProps.getProperty("BURY_BLAST_PARAMS"));

			if(curManData.getCAPArgs().length() > 0)
				txtCapArgs.setText(curManData.getCAPArgs());
			else
				txtCapArgs.setText(theProps.getProperty("CAP_ARGS"));

			if(curManData.getTCBlastEval().length() > 0)
				txtTCBlastEval.setText(curManData.getTCBlastEval());
			else
				txtTCBlastEval.setText(theProps.getProperty("TC_BLAST_EVAL"));

			if(curManData.getTCBlastParams().length() > 0)
				txtTCBlastParams.setText(curManData.getTCBlastParams());
			else
				txtTCBlastParams.setText(theProps.getProperty("TC_BLAST_PARAMS"));

			txtUserESTSelfBlast.setText(curManData.getUserESTSelfBlast());
				
			if(curManData.getNumTCs() > 0) {
				tblTC.clearAll();
				for(int x=0; x<curManData.getNumTCs(); x++)
					tblTC.addRow(curManData.getTCAt(x));
			}
			else {
				tblTC.clearAll();
				boolean doneReadingTC = false;
				int TCIdx = 1;
				while(!doneReadingTC) {
					try {
						String val = theProps.getProperty("TC" + TCIdx);
						if(val.length() == 0)
							doneReadingTC = true;
						else
							tblTC.addRow(val);
						TCIdx++;
					}
					catch(Exception e) {
						doneReadingTC = true;
					}
				}
			}

			nFrameMode = FRAME_MODE_ASSEM;
			mainPanel.setVisible(false);
			pnlAssemblyOptions.setVisible(true);
			
			updateUI();
		}
		catch(Exception e) {ErrorReport.prtReport(e, "Error setting Assembly options");}
	}
	private void actionOptionsAnno() {
		if(curManData.getUnitransType() < 0)
			cmbAnnoUnitransType.setSelectedIndex(0);
		else
			cmbAnnoUnitransType.setSelectedIndex(curManData.getUnitransType());
		
		if(curManData.getUnitransSelfBlast() == null)
			chkSelfBlast.setSelected(false);
		else {
			chkSelfBlast.setSelected(true);
			if(curManData.getUnitransSelfBlast().length() > 0)
				txtSelfBlast.setText(curManData.getUnitransSelfBlast());
			if(curManData.getUnitransSelfBlastParams().length() > 0)
				txtSelfBlastArgs.setText(curManData.getUnitransSelfBlastParams());
		}
		if(curManData.getUnitransTSelfBlast() == null)
			chkTSelfBlast.setSelected(false);
		else {
			chkTSelfBlast.setSelected(true);
			if(curManData.getUnitransTSelfBlast().length() > 0)
				txtTSelfBlast.setText(curManData.getUnitransTSelfBlast());
			if(curManData.getUnitransTSelfBlastParams().length() > 0)
				txtSelfBlastArgs.setText(curManData.getUnitransTSelfBlastParams());
		}
		
		if(curManData.getPairsLimit() > 0)
			txtPairsLimit.setText("" + curManData.getPairsLimit());

		cmbGODB.removeAllItems();
		Vector<String> goList = getGODBs();
		cmbGODB.addItem(" None  ");
									
		for(int x=0; x<goList.size(); x++)
			cmbGODB.addItem("  " + goList.get(x) + "  ");
		
		if(goList.contains(curManData.getGODB()))
		{
			cmbGODB.setSelectedIndex(goList.indexOf(curManData.getGODB()) + 1);
		}
		else
			cmbGODB.setSelectedIndex(0);
		
		nFrameMode = FRAME_MODE_ANNO;
		mainPanel.setVisible(false);
		pnlAnnoDBOptions.setVisible(true);
	}
	private void actionAnno() {
		try {
			if (!saveProject()) return;
			bBusy = true;
			updateUI();
			
			final String JAR_DIR = "java/jars";
			final String JAR = JAR_DIR + "/stcw.jar";
			final String MAXMEM = MAX_MEM;
			final String classPath = JAR ;
			final String cmd = "java -Xmx" + MAXMEM + "m -cp " + classPath + " jpave.annotator.CoreMain " + curManData.getProjectName();

			Process pr = Runtime.getRuntime().exec(cmd);
			pr.getOutputStream().flush();
			OutputHandler oh = new OutputHandler(pr.getErrorStream());
			InputHandler ih = new InputHandler(pr.getOutputStream());
			
			oh.start();
			ih.start();
			pr.waitFor();
			oh.Stop();
			ih.Stop();

			if (pr.exitValue() != 255) // not cancelled
			{
				updateAnnoDBLoadStatus();
			}
			bBusy = false;
			updateUI();
		} catch (Exception e) {ErrorReport.prtReport(e, "Error launching annotater");}
	}
	private void actionGO() {
		try 
		{
			if (!saveProject()) return;
			bBusy = true;
			updateUI();
			
			final String JAR_DIR = "java/jars";
			final String JAR = JAR_DIR + "/stcw.jar";
			final String MAXMEM = MAX_MEM;
			final String classPath = JAR;
			final String cmd = "java -Xmx" + MAXMEM + "m -cp " + classPath + " jpave.annotator.CoreMain " + curManData.getProjectName() + " -G";
			Process pr = Runtime.getRuntime().exec(cmd);
			pr.getOutputStream().flush();
			OutputHandler oh = new OutputHandler(pr.getErrorStream());
			InputHandler ih = new InputHandler(pr.getOutputStream());
			
			oh.start();
			ih.start();
			pr.waitFor();
			oh.Stop();
			ih.Stop();

			if (pr.exitValue() != 255) // not cancelled
			{
				updateAnnoDBLoadStatus();
			}
			bBusy = false;
			updateUI();
		} 
		catch (Exception e) {ErrorReport.prtReport(e, "Error updating GO");}
	}
	private void actionView() {
		try {
			String target = curManData.getPAVEDB() + ":" + curManData.getAssemblyID();
			if(!hostsObj.host.equals("localhost"))
				target = hostsObj.host + ":" + target;
			
			final String JAR_DIR = "java/jars";
			final String JAR = JAR_DIR + "/stcw.jar";
			final String MAXMEM = MAX_MEM;
			final String classPath = JAR ;
			final String cmd = "java -Xmx" + MAXMEM + "m -cp " + classPath + " jpave.query_interface.JPaveMain " 
				+ target;

			System.err.println("Launching viewSingleTCW for " + 
					hostsObj.host + ":" + curManData.getPAVEDB() + ":" + curManData.getAssemblyID());
			Process pr = Runtime.getRuntime().exec(cmd);
			pr.getOutputStream().flush();
			OutputHandler oh = new OutputHandler(pr.getErrorStream());
			InputHandler ih = new InputHandler(pr.getOutputStream());
			
			oh.start();
			ih.start();
			pr.waitFor();
			oh.Stop();
			ih.Stop();
		} catch (Exception e) {ErrorReport.prtReport(e, "Error launching viewSingleTCW");}
	}
	private void actionDE() {
		try {
			final String JAR_DIR = "java/jars";
			final String JAR = JAR_DIR + "/stcw.jar";
			final String MAXMEM = MAX_MEM;
			final String classPath = JAR;
			String jriPath = " -Djava.library.path=" + PaveProps.getExtDir() + "/jri ";
			final String cmd = "java " + jriPath + " -Xmx" + MAXMEM + "m -cp " + classPath + " jpave.qr.QRMain " 
				+ curManData.getAssemblyID() + ":" +  curManData.getPAVEDB() + ":" + hostsObj.host;
			System.err.println("Launching DE for " + 
					hostsObj.host + ":" + curManData.getPAVEDB() + ":" + curManData.getAssemblyID());
			String rHome = System.getenv("R_HOME");
			if (rHome == null)
			{
				System.err.println("You must set the R_HOME environment variable to the location of the R installation.");
				return;
			}
			Process pr = Runtime.getRuntime().exec(cmd,null);
			pr.getOutputStream().flush();
			OutputHandler oh = new OutputHandler(pr.getErrorStream());
			InputHandler ih = new InputHandler(pr.getOutputStream());
			
			oh.start();
			ih.start();
			pr.waitFor();
			oh.Stop();
			ih.Stop();
		} catch (Exception e) {ErrorReport.prtReport(e, "Error launching DE");}
	}
	
	/***********************************************************
	 * transLibPanel - table and Add/Edit/Remove on Main window
	 */
	private void createTransLibPanel() {
		pnlTransLib = new JPanel();
		pnlTransLib.setLayout(new BoxLayout(pnlTransLib, BoxLayout.LINE_AXIS));
		pnlTransLib.setBackground(BGCOLOR);
		pnlTransLib.setAlignmentX(Component.LEFT_ALIGNMENT);
		
		transLibraryTable = new ManagerTable(ManagerTable.TRANS_LIB_MODE);
		transLibraryTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent arg0) {
				updateUI();
			}
		});
		
		sPaneTransLibrary = new JScrollPane();
		sPaneTransLibrary.setViewportView(transLibraryTable);
		transLibraryTable.getTableHeader().setBackground(Color.WHITE);
		sPaneTransLibrary.setColumnHeaderView(transLibraryTable.getTableHeader());
		sPaneTransLibrary.setAlignmentX(Component.LEFT_ALIGNMENT);
    	
		sPaneTransLibrary.getViewport().setBackground(Color.WHITE);
		sPaneTransLibrary.getHorizontalScrollBar().setBackground(Color.WHITE);
		sPaneTransLibrary.getVerticalScrollBar().setBackground(Color.WHITE);
		sPaneTransLibrary.getHorizontalScrollBar().setForeground(Color.WHITE);
		sPaneTransLibrary.getVerticalScrollBar().setForeground(Color.WHITE);
		
		sPaneTransLibrary.getViewport().setMaximumSize(new Dimension(400, 10));
		sPaneTransLibrary.getViewport().setPreferredSize(new Dimension(400, 10));
		sPaneTransLibrary.getViewport().setMinimumSize(new Dimension(400, 10));
		pnlTransLib.add(sPaneTransLibrary);
		pnlTransLib.add(Box.createHorizontalStrut(5));
		
		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.PAGE_AXIS));
		buttonPanel.setBackground(BGCOLOR);
		
		btnAddTransLib = new JButton("Add");
		btnAddTransLib.setBackground(MENUCOLOR);
		btnAddTransLib.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				nFrameMode = FRAME_MODE_TRANS_LIB_EDIT;
				bAddTransLib = true;
				updateTransLibEditUI(curManData.addNewTransLib(), true);
				mainPanel.setVisible(false);
				pnlTransLibEdit.setVisible(true);				

				updateUI();
			}
		});
		
		btnEditTransLib = new JButton("Edit");
		btnEditTransLib.setBackground(MENUCOLOR);
		btnEditTransLib.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				nFrameMode = FRAME_MODE_TRANS_LIB_EDIT;
				bAddTransLib = false;
				// CAS 5/15/15 want to be able to edit transcript if database does not exist
				updateTransLibEditUI(transLibraryTable.getSelectedRow(), !dbExists);

				mainPanel.setVisible(false);
				pnlTransLibEdit.setVisible(true);
			}
		});
		btnEditTransLib.setEnabled(false);
		
		btnRemoveTransLib = new JButton("Remove");
		btnRemoveTransLib.setBackground(BGCOLOR);
		btnRemoveTransLib.setEnabled(false);
		btnRemoveTransLib.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				curManData.removeTransLib(transLibraryTable.getSelectedRow());
				saveProject();
				transLibraryTable.getSelectionModel().clearSelection();

				updateUI();
			}
		});
		
		btnAddTransLib.setMinimumSize(btnRemoveTransLib.getPreferredSize());
		btnAddTransLib.setMaximumSize(btnRemoveTransLib.getPreferredSize());
		btnEditTransLib.setMinimumSize(btnRemoveTransLib.getPreferredSize());
		btnEditTransLib.setMaximumSize(btnRemoveTransLib.getPreferredSize());
		
		buttonPanel.add(btnAddTransLib);
		buttonPanel.add(Box.createVerticalStrut(5));
		buttonPanel.add(btnEditTransLib);
		buttonPanel.add(Box.createVerticalStrut(5));
		buttonPanel.add(btnRemoveTransLib);
		
		buttonPanel.setMaximumSize(buttonPanel.getPreferredSize());
		
		pnlTransLib.add(buttonPanel);
	}
	/**************************************************************
	 * Table of TransLibs with Edit/Define Reps buttons
	 */
	private void createExpLibPanel() {
		pnlExpLib = new JPanel();
		pnlExpLib.setLayout(new BoxLayout(pnlExpLib, BoxLayout.LINE_AXIS));
		pnlExpLib.setBackground(BGCOLOR);
		pnlExpLib.setAlignmentX(Component.LEFT_ALIGNMENT);
		
		expLibraryTable = new ManagerTable(ManagerTable.EXP_LIB_MODE);
		expLibraryTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent arg0) {
				updateUI();
			}
		});
			
		sPaneExpLibrary = new JScrollPane();
		sPaneExpLibrary.setViewportView(expLibraryTable);
		expLibraryTable.getTableHeader().setBackground(Color.WHITE);
		sPaneExpLibrary.setColumnHeaderView(expLibraryTable.getTableHeader());
		sPaneExpLibrary.setAlignmentX(Component.LEFT_ALIGNMENT);
    	
		sPaneExpLibrary.getViewport().setBackground(Color.WHITE);
		sPaneExpLibrary.getHorizontalScrollBar().setBackground(Color.WHITE);
		sPaneExpLibrary.getVerticalScrollBar().setBackground(Color.WHITE);
		sPaneExpLibrary.getHorizontalScrollBar().setForeground(Color.WHITE);
		sPaneExpLibrary.getVerticalScrollBar().setForeground(Color.WHITE);
		
		sPaneExpLibrary.getViewport().setMaximumSize(new Dimension(TABLE_WIDTH, 10));
		sPaneExpLibrary.getViewport().setPreferredSize(new Dimension(TABLE_WIDTH, 10));
		sPaneExpLibrary.getViewport().setMinimumSize(new Dimension(TABLE_WIDTH, 10));
    		pnlExpLib.add(sPaneExpLibrary);
    		pnlExpLib.add(Box.createHorizontalStrut(5));
		
		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.PAGE_AXIS));
		buttonPanel.setBackground(BGCOLOR);
		
		btnDefRep = new JButton("Define Replicates");
		btnDefRep.setBackground(MENUCOLOR);
		btnDefRep.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				Vector<String> reps = new Vector<String> ();
				Vector<String> libs = new Vector<String> ();
				Vector<String> prefix = new Vector<String> (); 
				Vector<String> transLib = new Vector<String> ();
				
				for(int x=0; x<curManData.getNumExpLibs(); x++) {
					//Only add non groups
					if(curManData.getExpLibraryAt(x).getNumReps() <= 1) {
						String libid = curManData.getExpLibraryAt(x).getLibID();
						reps.add(libid);
						transLib.add(curManData.getExpLibraryAt(x).getTransID());
						prefix.add(curManData.getExpLibraryAt(x).getPrefix()); 
						
						if(libid.matches("[a-z0-9A-Z_]+[0-9]+")) {
							Pattern pattern = Pattern.compile("[a-z0-9A-Z_]*[^0-9]+");
							Matcher matcher = pattern.matcher(libid);
							
							if(matcher.find()) {
								String val = matcher.group();
								while(val.endsWith("_"))
									val = val.substring(0, val.length()-1);
								libs.add(val);
							}
							else
								libs.add("");
						}
						else
							libs.add("");
					}
				}
				
				for(int x=0; x<curManData.getNumReps(); x++) {
						reps.add(curManData.getRepLibraryAt(x).getRepID());
						libs.add(curManData.getRepLibraryAt(x).getLibID());
						prefix.add(curManData.getRepLibraryAt(x).getExpPrefix());
						transLib.add(curManData.getRepLibraryAt(x).getTransID());
				}
				
				//Cleanup: remove defined groups
				for(int x=reps.size()-1; x>=0; x--) {
					if(libs.contains(reps.get(x)) && !reps.get(x).equals(libs.get(x))) {
						libs.remove(x);
						reps.remove(x);
						prefix.remove(x); 
						transLib.remove(x);
					}
				}
				pnlGenReps.setRepList(reps, prefix, libs, transLib);
				mainPanel.setVisible(false);
				pnlGenReps.setVisible(true);
			}
		});
		btnEditExpLib = new JButton("Edit Attributes");
		btnEditExpLib.setBackground(MENUCOLOR);
		btnEditExpLib.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				nFrameMode = FRAME_MODE_EXP_LIB_EDIT;
				updateExpLibEditUI(expLibraryTable.getSelectedRow(), false);
				mainPanel.setVisible(false);
				pnlExpLibEdit.setVisible(true);
				
				updateUI();
			}
		});
		btnEditExpLib.setEnabled(false);
		
		btnEditExpLib.setMinimumSize(btnDefRep.getPreferredSize());
		btnEditExpLib.setMaximumSize(btnDefRep.getPreferredSize());
		btnDefRep.setMaximumSize(btnDefRep.getPreferredSize());
		btnDefRep.setMinimumSize(btnDefRep.getPreferredSize());
		
		buttonPanel.add(Box.createVerticalStrut(40));
		buttonPanel.add(btnDefRep);
		buttonPanel.add(Box.createVerticalStrut(5));
		buttonPanel.add(btnEditExpLib);
		buttonPanel.add(Box.createVerticalStrut(40));
		pnlExpLib.add(buttonPanel);
	}
	/********************************************************
	 * annoDB panel on main window with Add/Edit/Remove/MoveUp/MoveDown
	 */
	private void createAnnoDBPanel() {
		pnlAnnoDB = new JPanel();
		pnlAnnoDB.setLayout(new BoxLayout(pnlAnnoDB, BoxLayout.LINE_AXIS));
		pnlAnnoDB.setBackground(BGCOLOR);
		pnlAnnoDB.setAlignmentX(Component.LEFT_ALIGNMENT);
		
		annoDBTable = new ManagerTable(ManagerTable.ANNODB_MODE);
		annoDBTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent arg0) {
				updateUI();
			}
		});	
		annoDBTable.addMouseListener(new MouseAdapter() {
			public void mouseReleased(MouseEvent ev) {
				for(int x=0; x<annoDBTable.getRowCount(); x++) {
					curManData.getAnnoDBAt(x).setSelected((Boolean)annoDBTable.getModel().getValueAt(x, 0));
				}
			}
		});
	
		sPaneAnnoDB = new JScrollPane();
		sPaneAnnoDB.setViewportView(annoDBTable);
	    	annoDBTable.getTableHeader().setBackground(Color.WHITE);
	    	sPaneAnnoDB.setColumnHeaderView(annoDBTable.getTableHeader());
	    	sPaneAnnoDB.setAlignmentX(Component.LEFT_ALIGNMENT);
	    	
	    	sPaneAnnoDB.getViewport().setBackground(Color.WHITE);
	    	sPaneAnnoDB.getHorizontalScrollBar().setBackground(Color.WHITE);
	    	sPaneAnnoDB.getVerticalScrollBar().setBackground(Color.WHITE);
	    	sPaneAnnoDB.getHorizontalScrollBar().setForeground(Color.WHITE);
	    	sPaneAnnoDB.getVerticalScrollBar().setForeground(Color.WHITE);
			
	    	sPaneAnnoDB.getViewport().setMaximumSize(new Dimension(TABLE_WIDTH, 10));
	    	sPaneAnnoDB.getViewport().setPreferredSize(new Dimension(TABLE_WIDTH, 10));
	    	sPaneAnnoDB.getViewport().setMinimumSize(new Dimension(TABLE_WIDTH, 10));
	    	pnlAnnoDB.add(sPaneAnnoDB);
	    	pnlAnnoDB.add(Box.createHorizontalStrut(5));
		
		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.PAGE_AXIS));
		buttonPanel.setBackground(BGCOLOR);
		
		btnAddAnnoDB = new JButton("Add");
		btnAddAnnoDB.setBackground(MENUCOLOR);
		btnAddAnnoDB.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				nFrameMode = FRAME_MODE_ANNO_DB_EDIT;
				updateAnnoDBEditUI(curManData.addNewAnnoDB(), true);
				mainPanel.setVisible(false);
				pnlAnnoDBEdit.setVisible(true);				

				updateUI();
			}
		});
		
		btnEditAnnoDB = new JButton("Edit");
		btnEditAnnoDB.setBackground(MENUCOLOR);
		btnEditAnnoDB.setEnabled(false);
		btnEditAnnoDB.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				nFrameMode = FRAME_MODE_ANNO_DB_EDIT;
				int row = annoDBTable.getSelectedRow();
				updateAnnoDBEditUI(row, false);

				mainPanel.setVisible(false);
				pnlAnnoDBEdit.setVisible(true);				
			}
		});
		
		btnRemoveAnnoDB = new JButton("Remove");
		btnRemoveAnnoDB.setBackground(BGCOLOR);
		btnRemoveAnnoDB.setEnabled(false);
		btnRemoveAnnoDB.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				int row = annoDBTable.getSelectedRow();
				if (!curManData.getAnnoDBAt(row).isLoaded()) {
					curManData.removeAnnoDB(row);
					annoDBTable.getSelectionModel().clearSelection();
					updateUI();
				}
				else {
					JOptionPane.showMessageDialog(getInstance(), "Cannot remove an annoDB that is in the database");
				}
			}
		});
		
		btnMoveUpAnnoDB = new JButton("Move Up");
		btnMoveUpAnnoDB.setBackground(BGCOLOR);
		btnMoveUpAnnoDB.setEnabled(false);
		btnMoveUpAnnoDB.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				int row = annoDBTable.getSelectedRow();
				curManData.moveAnnoDB(row, row-1);
				updateUI();
				annoDBTable.getSelectionModel().setSelectionInterval(row-1, row-1);
			}
		});
		
		btnMoveDownAnnoDB = new JButton("Move Down");
		btnMoveDownAnnoDB.setBackground(BGCOLOR);
		btnMoveDownAnnoDB.setEnabled(false);
		btnMoveDownAnnoDB.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				int row = annoDBTable.getSelectedRow();
				curManData.moveAnnoDB(row, row+1);
				updateUI();
				annoDBTable.getSelectionModel().setSelectionInterval(row+1, row+1);
			}
		});
		
		btnAddAnnoDB.setMinimumSize(btnMoveDownAnnoDB.getPreferredSize());
		btnAddAnnoDB.setMaximumSize(btnMoveDownAnnoDB.getPreferredSize());
		btnEditAnnoDB.setMinimumSize(btnMoveDownAnnoDB.getPreferredSize());
		btnEditAnnoDB.setMaximumSize(btnMoveDownAnnoDB.getPreferredSize());
		btnRemoveAnnoDB.setMinimumSize(btnMoveDownAnnoDB.getPreferredSize());
		btnRemoveAnnoDB.setMaximumSize(btnMoveDownAnnoDB.getPreferredSize());
		btnMoveUpAnnoDB.setMinimumSize(btnMoveDownAnnoDB.getPreferredSize());
		btnMoveUpAnnoDB.setMaximumSize(btnMoveDownAnnoDB.getPreferredSize());
		
		buttonPanel.add(btnAddAnnoDB);
		buttonPanel.add(Box.createVerticalStrut(5));
		buttonPanel.add(btnEditAnnoDB);
		buttonPanel.add(Box.createVerticalStrut(5));
		buttonPanel.add(btnRemoveAnnoDB);
		buttonPanel.add(Box.createVerticalStrut(5));
		buttonPanel.add(btnMoveUpAnnoDB);
		buttonPanel.add(Box.createVerticalStrut(5));
		buttonPanel.add(btnMoveDownAnnoDB);
		
		buttonPanel.setMaximumSize(buttonPanel.getPreferredSize());
		
		pnlAnnoDB.add(buttonPanel);
	}
	
	/*****************************************************************
	 * XXX routine for main window
	 */
	private Vector<String> getGODBs() {
		Vector<String> retVal = new Vector<String> ();
		try {
			Class.forName("com.mysql.jdbc.Driver");
			String dbstr = "jdbc:mysql://" + hostsObj.host + "/";
			Connection con = null; 

			con = DriverManager.getConnection(dbstr, hostsObj.user, hostsObj.pass);
			Statement st = con.createStatement();
				
			ResultSet rset = st.executeQuery("show databases LIKE 'go_%'");
			while(rset.next()) {
				retVal.add(rset.getString(1));
			}
			rset.close();						
		}
		catch(Exception e) {
			ErrorReport.prtReport(e, "Error getting GO databases");
		}
		return retVal;
	}
	
	public boolean saveProject() {
		updateProjectData();
		if(curManData != null) {
			String dupLib = ManagerData.hasDuplicates(curManData);
			if(dupLib !=null) { // CAS 1/14/15 more descritive message
				JOptionPane.showMessageDialog(this, 
						 dupLib + "\nMake your Lib names unique.", 
						"Error - duplicate libraries", JOptionPane.PLAIN_MESSAGE);
				return false;
			}
			else if(!ManagerData.hasValidID(curManData)) {
				JOptionPane.showMessageDialog(this, curManData + "is invalid. \n\nThe ID may only contain letters, '_' or digits", 
						"Error - invalid ID", JOptionPane.PLAIN_MESSAGE);
				return false;
			}
			else 
				return ManagerData.saveLIBcfg_sTCWcfg(curManData);
		}
		return false;
	}
	
	private void refreshProjectList() {
		String [] projs = getLibraryList(false);
		
		cmbProjects.removeAllItems();
		
		cmbProjects.addItem("Select...");
		
		for(int x=0; x<projs.length; x++)
			cmbProjects.addItem(projs[x]);
		
		cmbProjects.setSelectedIndex(0);
	}
	private void removeSelectedProject() {
		try {
			File fLib = getLibPath();
			File fProj = getProjPath();
			 			
			if(deleteDir(fLib) && deleteDir(fProj))
				System.out.println("\nProject removed successfully");
			else
				System.out.println("\nProject remove failed");

			refreshProjectList();
			curManData = null;
			updateUI();
		}
		catch(Exception e) {
			ErrorReport.prtReport(e, "Error removing project");}
	}
	
	private boolean deleteDir(File f) {
		boolean retVal = true;
		if(f.isDirectory()) {
			for (File subFile : f.listFiles())
				retVal = retVal && deleteDir(subFile);
		}
		boolean delResult = f.delete();
		if(delResult)
			System.out.println("Deleting: " + f.getAbsolutePath());
		else
			System.out.println("Failed to delete " + f.getAbsolutePath());
		
		return retVal && delResult;
	}
	
	/***********************************************************
	 * XXX Panels that replace main window
	 * there are also some in files such as EditAnnoPanel.java
	 */
	
	/*************************************************
	 * annotation options panel that replaces main window
	 */
	private void createAnnoDBOptionPanel() {
		pnlAnnoDBOptions = new JPanel();
		pnlAnnoDBOptions.setLayout(new BoxLayout(pnlAnnoDBOptions, BoxLayout.PAGE_AXIS));
		pnlAnnoDBOptions.setBackground(BGCOLOR);
		pnlAnnoDBOptions.setAlignmentX(Component.LEFT_ALIGNMENT);
		pnlAnnoDBOptions.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		
		JPanel innerPanel = new JPanel();
		innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.PAGE_AXIS));
		innerPanel.setBackground(BGCOLOR);
		innerPanel.setAlignmentX(Component.CENTER_ALIGNMENT);

		JPanel row = createRowPanel();

		JLabel title = new JLabel("Annotation Options");
		title.setFont(pnlAnnoDBOptions.getFont().deriveFont(Font.BOLD, 18));
		
		row.add(Box.createHorizontalGlue());
		row.add(title);
		row.add(Box.createHorizontalGlue());
		innerPanel.add(row);
		innerPanel.add(Box.createVerticalStrut(20));
		
		innerPanel.add(new JLabel("annoDB ANNOTATION:"));
		innerPanel.add(Box.createVerticalStrut(10));
		row = createRowPanel();
		
		cmbAnnoUnitransType = new ButtonComboBox();
		cmbAnnoUnitransType.addItem("All");
		cmbAnnoUnitransType.addItem("Contig Only");
		cmbAnnoUnitransType.addItem("Singletons Only");
		cmbAnnoUnitransType.setSelectedIndex(0);
		cmbAnnoUnitransType.setBackground(Color.WHITE);
			
		row.add(new JLabel("For assembled"));
		row.add(Box.createHorizontalStrut(5));
		row.add(cmbAnnoUnitransType);
		row.setMaximumSize(row.getPreferredSize());
		innerPanel.add(row);
		innerPanel.add(Box.createVerticalStrut(30));
		
		txtDefaultBlastArgs = new JTextArea(2, BLAST_ARGS_TEXTFIELD_WIDTH);
		txtDefaultBlastArgs.setText(BlastArgs.getBlastxOptions());
		txtDefaultBlastArgs.setLineWrap(true);
		txtDefaultBlastArgs.setWrapStyleWord(true);
		JScrollPane tempPane = new JScrollPane(txtDefaultBlastArgs);
		
		// GO
		cmbGODB = new ButtonComboBox();
		cmbGODB.addItem("      None      ");
		cmbGODB.setBackground(BGCOLOR);
		cmbGODB.setMaximumSize(cmbGODB.getPreferredSize());
			
		row = createRowPanel();		
		JLabel goDB = new JLabel("GO Database"); 
		row.add(goDB);
		row.add(Box.createHorizontalStrut(10));
		row.add(cmbGODB);
		innerPanel.add(row);
		innerPanel.add(Box.createVerticalStrut(25));
		
		innerPanel.add(new JLabel("SIMILAR SEQUENCES:"));
		innerPanel.add(Box.createVerticalStrut(10));

		chkSelfBlast = new JCheckBox("Run Nucleotide Self Blast (Megablast or blastn)");
		chkSelfBlast.setBackground(BGCOLOR);
		
		txtSelfBlast = new FileTextField(TEXTFIELD_WIDTH);
		txtSelfBlast.setMaximumSize(txtSelfBlast.getPreferredSize());
		txtSelfBlast.addCaretListener(new CaretListener() {
			public void caretUpdate(CaretEvent arg0) {
				if(txtSelfBlast.getText().length() > 0)
					chkSelfBlast.setSelected(false);
			}
		});
		
		txtSelfBlastArgs = new JTextArea(2, BLAST_ARGS_TEXTFIELD_WIDTH);
		txtSelfBlastArgs.setText(BlastArgs.getBlastnOptions());
		txtSelfBlastArgs.setLineWrap(true);
		txtSelfBlastArgs.setWrapStyleWord(true);
		tempPane = new JScrollPane(txtSelfBlastArgs);
		
		row = createRowPanel();		
		row.add(chkSelfBlast);
		
		innerPanel.add(row);
		innerPanel.add(Box.createVerticalStrut(5));

		row = createRowPanel();		
		JLabel selfBlastArgLbl = new JLabel("Arguments");
		row.add(Box.createHorizontalStrut(20));
		row.add(selfBlastArgLbl);
		row.add(Box.createHorizontalStrut(5));
		row.add(tempPane);
		
		innerPanel.add(row);
		innerPanel.add(Box.createVerticalStrut(5));
		
		row = createRowPanel();		
		row.add(new JLabel("Or use existing"));
		row.add(Box.createHorizontalStrut(5));
		row.add(txtSelfBlast);
		
		innerPanel.add(row);
		innerPanel.add(Box.createVerticalStrut(20));
				
		chkTSelfBlast = new JCheckBox("Run Translated Self Blast (tblastx)");
		chkTSelfBlast.setBackground(BGCOLOR);
		
		txtTSelfBlast = new FileTextField(TEXTFIELD_WIDTH);
		txtTSelfBlast.setMaximumSize(txtTSelfBlast.getPreferredSize());
		txtTSelfBlast.addCaretListener(new CaretListener() {
			public void caretUpdate(CaretEvent arg0) {
				if(txtTSelfBlast.getText().length() > 0)
					chkTSelfBlast.setSelected(false);
			}
		});
		
		txtTSelfBlastArgs = new JTextArea(2, BLAST_ARGS_TEXTFIELD_WIDTH);
		txtTSelfBlastArgs.setText(BlastArgs.getTblastxOptions());
		txtTSelfBlastArgs.setLineWrap(true);
		txtTSelfBlastArgs.setWrapStyleWord(true);
		 tempPane = new JScrollPane(txtTSelfBlastArgs);

		row = createRowPanel();		
		row.add(chkTSelfBlast);
		
		innerPanel.add(row);
		innerPanel.add(Box.createVerticalStrut(5));

		row = createRowPanel();		
		tSelfBlastArgLbl = new JLabel("Arguments");
		row.add(Box.createHorizontalStrut(20));
		row.add(tSelfBlastArgLbl);
		row.add(Box.createHorizontalStrut(5));
		row.add(tempPane);
		
		innerPanel.add(row);
		innerPanel.add(Box.createVerticalStrut(5));

		tSelfBlastExistLbl = new JLabel("Or use existing");
		row = createRowPanel();		
		row.add(tSelfBlastExistLbl);
		row.add(Box.createHorizontalStrut(5));
		row.add(txtTSelfBlast);
			
		innerPanel.add(row);
		innerPanel.add(Box.createVerticalStrut(20));
		
		txtPairsLimit  = new JTextField(NUM_FIELD_WIDTH);
		txtPairsLimit.setMaximumSize(txtPairsLimit.getPreferredSize());
		txtPairsLimit.setMinimumSize(txtPairsLimit.getPreferredSize());
		txtPairsLimit.setText(CoreMain.defaultPairsLimit + "");
			
		row = createRowPanel();		
		JLabel pairsLimit = new JLabel("Pairs limit"); 
		row.add(pairsLimit);
		row.add(Box.createHorizontalStrut(10));
		row.add(txtPairsLimit);
		innerPanel.add(row);
		innerPanel.add(Box.createVerticalStrut(25));
		
		JButton btnResetDefaults = new JButton("Reset To Default");
		btnResetDefaults.setBackground(BGCOLOR);
		btnResetDefaults.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				cmbAnnoUnitransType.setSelectedIndex(0);
				chkSelfBlast.setSelected(true);
				txtSelfBlast.setText("");
				txtSelfBlastArgs.setText(BlastArgs.getBlastnOptions());
				chkTSelfBlast.setSelected(true);
				txtTSelfBlast.setText("");
				txtTSelfBlastArgs.setText(BlastArgs.getTblastxOptions());
				txtPairsLimit.setText(CoreMain.defaultPairsLimit + "");
			}
		});

		JButton btnKeep = new JButton("Keep");
		btnKeep.setBackground(BGCOLOR);
		btnKeep.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				pnlAnnoDBOptions.setVisible(false);
				mainPanel.setVisible(true);

				if(cmbAnnoUnitransType.getSelectedIndex() > 0) {
					curManData.setUnitransType(cmbAnnoUnitransType.getSelectedIndex());
				}
				
				if(!chkSelfBlast.isSelected())
					curManData.setUnitransSelfBlast(null);
				else {
					curManData.setUnitransSelfBlast(txtSelfBlast.getText());
				}
				curManData.setUnitransSelfBlastParams(txtSelfBlastArgs.getText().replace('\n', ' '));
				if(!chkTSelfBlast.isSelected())
					curManData.setUnitransTSelfBlast(null);
				else {
					curManData.setUnitransTSelfBlast(txtSelfBlast.getText());
				}
				curManData.setUnitransTSelfBlastParams(txtTSelfBlastArgs.getText().replace('\n', ' '));
				
				if(txtPairsLimit.getText().length() > 0) {
					try {
						curManData.setPairsLimit(Integer.parseInt(txtPairsLimit.getText()));
					}
					catch(Exception err) {
						curManData.setPairsLimit(-1);
					}
				}
				else
					curManData.setPairsLimit(-1);
				
				curManData.setGODB("");
				if(cmbGODB.getSelectedIndex() > 0)
				{
					curManData.setGODB(cmbGODB.getSelectedItem().trim());
				}
				
				updateUI();
				saveProject();
				nFrameMode = FRAME_MODE_MAIN;
			}
		});
		
		JButton btnDiscard = new JButton("Discard");
		btnDiscard.setBackground(BGCOLOR);
		btnDiscard.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				pnlAnnoDBOptions.setVisible(false);
				mainPanel.setVisible(true);
				
				nFrameMode = FRAME_MODE_MAIN;
			}
		});
		
		JButton btnHelp = new JButton("Help");
		btnHelp.setBackground(HELPCOLOR);
		btnHelp.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				UserPrompt.displayHTMLResourceHelp(getInstance(), 
						"Annotation Options Help", "html/runSingleTCW/AnnotationOptions.html");
			}
		});
		
		JPanel buttonRow = new JPanel();
		buttonRow.setLayout(new BoxLayout(buttonRow, BoxLayout.LINE_AXIS));
		buttonRow.setAlignmentX(Component.CENTER_ALIGNMENT);
		buttonRow.setBackground(BGCOLOR);
				
		buttonRow.add(btnKeep);
		buttonRow.add(Box.createHorizontalStrut(15));
		buttonRow.add(btnDiscard);
		buttonRow.add(Box.createHorizontalStrut(15));
		buttonRow.add(btnResetDefaults);
		buttonRow.add(Box.createHorizontalStrut(15));
		buttonRow.add(btnHelp);
		
		buttonRow.setMaximumSize(buttonRow.getPreferredSize());
		buttonRow.setMinimumSize(buttonRow.getPreferredSize());
		
		innerPanel.setMaximumSize(innerPanel.getPreferredSize());
		innerPanel.setMinimumSize(innerPanel.getPreferredSize());
		
		pnlAnnoDBOptions.add(innerPanel);
		pnlAnnoDBOptions.add(Box.createVerticalStrut(20));
		pnlAnnoDBOptions.add(buttonRow);

		pnlAnnoDBOptions.setVisible(false);
	}

	/*********************************************************
	 * assembly option panel that replaces main window
	 */
	private void createAssemblyOptionPanel() {
		try {
			pnlAssemblyOptions = new JPanel();
			pnlAssemblyOptions.setLayout(new BoxLayout(pnlAssemblyOptions, BoxLayout.PAGE_AXIS));
			pnlAssemblyOptions.setBackground(BGCOLOR);
			pnlAssemblyOptions.setAlignmentX(Component.LEFT_ALIGNMENT);
			pnlAssemblyOptions.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
			
			JPanel innerPanel = new JPanel();
			innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.PAGE_AXIS));
			innerPanel.setBackground(BGCOLOR);
			innerPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
			
			JPanel row = createRowPanel();	
			
			JLabel title = new JLabel("Assembly Options");
			title.setFont(pnlAssemblyOptions.getFont().deriveFont(Font.BOLD, 18));
			
			row.add(Box.createHorizontalGlue());
			row.add(title);
			row.add(Box.createHorizontalGlue());
			innerPanel.add(row);
			innerPanel.add(Box.createVerticalStrut(20));

			row = createRowPanel();	

			chkSkipAssembly = new JCheckBox("Skip Assembly");
			chkSkipAssembly.setBackground(BGCOLOR);
			chkSkipAssembly.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {					
					curManData.setSkipAssembly(chkSkipAssembly.isSelected());
					updateUI();
				}
			});
			
			chkUseTransName = new JCheckBox("Use Sequence Names from File");
			chkUseTransName.setBackground(BGCOLOR);
			chkUseTransName.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					curManData.setUseTransNames(chkUseTransName.isSelected());
					updateUI();
				}
			});
			
			innerPanel.add(new JLabel("Assemble: "));
			innerPanel.add(Box.createVerticalStrut(5));
			
			lblClique 			= new JLabel("Clique");
			lblCliqueBlastEval 	= new JLabel("Clique Blast Eval");
			lblCliqueBlastParams = new JLabel("Clique Blast Params");
			lblSelfJoin	 		= new JLabel("Self Join");
			lblBuryBlastEval 	= new JLabel("Bury Blast Eval");
			lblBuryBlastIdentity = new JLabel("Bury Blast Identity");
			lblBuryBlastParams 	= new JLabel("Bury Blast Params");
			lblCapArgs 			= new JLabel("CAP Args");
			lblTCBlastEval		= new JLabel("TC Blast Eval");
			lblTCBlastParams	= new JLabel("TC Blast Params");
			lblUserESTSelfBlast  = new JLabel("User EST Self Blast"); 
			
			lblClique.setMaximumSize(lblCliqueBlastParams.getPreferredSize());
			lblClique.setMinimumSize(lblCliqueBlastParams.getPreferredSize());
			lblClique.setPreferredSize(lblCliqueBlastParams.getPreferredSize());
			lblCliqueBlastEval.setMaximumSize(lblCliqueBlastParams.getPreferredSize());
			lblCliqueBlastEval.setMinimumSize(lblCliqueBlastParams.getPreferredSize());
			lblCliqueBlastEval.setPreferredSize(lblCliqueBlastParams.getPreferredSize());
			lblCliqueBlastParams.setMaximumSize(lblCliqueBlastParams.getPreferredSize());
			lblCliqueBlastParams.setMinimumSize(lblCliqueBlastParams.getPreferredSize());
			lblCliqueBlastParams.setPreferredSize(lblCliqueBlastParams.getPreferredSize());
			lblSelfJoin.setMaximumSize(lblCliqueBlastParams.getPreferredSize());
			lblSelfJoin.setMinimumSize(lblCliqueBlastParams.getPreferredSize());
			lblSelfJoin.setPreferredSize(lblCliqueBlastParams.getPreferredSize());
			lblBuryBlastEval.setMaximumSize(lblCliqueBlastParams.getPreferredSize());
			lblBuryBlastEval.setMinimumSize(lblCliqueBlastParams.getPreferredSize());
			lblBuryBlastEval.setPreferredSize(lblCliqueBlastParams.getPreferredSize());
			lblBuryBlastIdentity.setMaximumSize(lblCliqueBlastParams.getPreferredSize());
			lblBuryBlastIdentity.setMinimumSize(lblCliqueBlastParams.getPreferredSize());
			lblBuryBlastIdentity.setPreferredSize(lblCliqueBlastParams.getPreferredSize());
			lblBuryBlastParams.setMaximumSize(lblCliqueBlastParams.getPreferredSize());
			lblBuryBlastParams.setMinimumSize(lblCliqueBlastParams.getPreferredSize());
			lblBuryBlastParams.setPreferredSize(lblCliqueBlastParams.getPreferredSize());
			lblCapArgs.setMaximumSize(lblCliqueBlastParams.getPreferredSize());
			lblCapArgs.setMinimumSize(lblCliqueBlastParams.getPreferredSize());
			lblCapArgs.setPreferredSize(lblCliqueBlastParams.getPreferredSize());
			lblTCBlastEval.setMaximumSize(lblCliqueBlastParams.getPreferredSize());
			lblTCBlastEval.setMinimumSize(lblCliqueBlastParams.getPreferredSize());
			lblTCBlastEval.setPreferredSize(lblCliqueBlastParams.getPreferredSize());
			lblTCBlastParams.setMaximumSize(lblCliqueBlastParams.getPreferredSize());
			lblTCBlastParams.setMinimumSize(lblCliqueBlastParams.getPreferredSize());
			lblTCBlastParams.setPreferredSize(lblCliqueBlastParams.getPreferredSize());
			lblUserESTSelfBlast.setMaximumSize(lblCliqueBlastParams.getPreferredSize());
			lblUserESTSelfBlast.setMinimumSize(lblCliqueBlastParams.getPreferredSize());
			lblUserESTSelfBlast.setPreferredSize(lblCliqueBlastParams.getPreferredSize());
			
			CaretListener changeListener = new CaretListener() {
				public void caretUpdate(CaretEvent e) {
					if(pnlClique.isValidVals() && pnlSelfJoin.isValidVals())
						btnKeepAssem.setEnabled(true);
					else
						btnKeepAssem.setEnabled(false);
				}
			};
			row = createRowPanel();		
			pnlClique = new MultiIntPanel(THREE_INT_VALS);
			pnlClique.setChangeListener(changeListener);
			row.add(lblClique);
			row.add(Box.createHorizontalStrut(10));
			row.add(pnlClique);
			innerPanel.add(row);
			innerPanel.add(Box.createVerticalStrut(10));
	
			row = createRowPanel();		
			txtCliqueBlastEval = new JTextField(TEXTFIELD_WIDTH);
			txtCliqueBlastEval.setMaximumSize(txtCliqueBlastEval.getPreferredSize());
			txtCliqueBlastEval.setMinimumSize(txtCliqueBlastEval.getPreferredSize());
			row.add(lblCliqueBlastEval);
			row.add(Box.createHorizontalStrut(10));
			row.add(txtCliqueBlastEval);
			innerPanel.add(row);
			innerPanel.add(Box.createVerticalStrut(10));
			
			row = createRowPanel();		
			txtCliqueBlastParams = new JTextField(TEXTFIELD_WIDTH);
			txtCliqueBlastParams.setMaximumSize(txtCliqueBlastParams.getPreferredSize());
			txtCliqueBlastParams.setMinimumSize(txtCliqueBlastParams.getPreferredSize());
			row.add(lblCliqueBlastParams);
			row.add(Box.createHorizontalStrut(10));
			row.add(txtCliqueBlastParams);
			innerPanel.add(row);
			innerPanel.add(Box.createVerticalStrut(10));
			
			row = createRowPanel();		
			pnlSelfJoin = new MultiIntPanel(THREE_INT_VALS);
			pnlSelfJoin.setChangeListener(changeListener);
			row.add(lblSelfJoin);
			row.add(Box.createHorizontalStrut(10));
			row.add(pnlSelfJoin);
			innerPanel.add(row);
	
			innerPanel.add(Box.createVerticalStrut(20));
			innerPanel.setMaximumSize(innerPanel.getPreferredSize());
			
			row = createRowPanel();		
			txtBuryBlastEval = new JTextField(TEXTFIELD_WIDTH);
			txtBuryBlastEval.setMaximumSize(txtBuryBlastEval.getPreferredSize());
			txtBuryBlastEval.setMinimumSize(txtBuryBlastEval.getPreferredSize());
			row.add(lblBuryBlastEval);
			row.add(Box.createHorizontalStrut(10));
			row.add(txtBuryBlastEval);
			innerPanel.add(row);
			innerPanel.add(Box.createVerticalStrut(5));
			
			row = createRowPanel();		
			txtBuryBlastIdentity = new JTextField(TEXTFIELD_WIDTH);
			txtBuryBlastIdentity.setMaximumSize(txtBuryBlastIdentity.getPreferredSize());
			txtBuryBlastIdentity.setMinimumSize(txtBuryBlastIdentity.getPreferredSize());
			row.add(lblBuryBlastIdentity);
			row.add(Box.createHorizontalStrut(10));
			row.add(txtBuryBlastIdentity);
			innerPanel.add(row);
			innerPanel.add(Box.createVerticalStrut(5));
			
			row = createRowPanel();		
			txtBuryBlastParams = new JTextField(TEXTFIELD_WIDTH);
			txtBuryBlastParams.setMaximumSize(txtBuryBlastParams.getPreferredSize());
			txtBuryBlastParams.setMinimumSize(txtBuryBlastParams.getPreferredSize());
			row.add(lblBuryBlastParams);
			row.add(Box.createHorizontalStrut(10));
			row.add(txtBuryBlastParams);
			innerPanel.add(row);
			innerPanel.add(Box.createVerticalStrut(5));
			
			row = createRowPanel();		
			txtCapArgs = new JTextField(TEXTFIELD_WIDTH);
			txtCapArgs.setMaximumSize(txtCapArgs.getPreferredSize());
			txtCapArgs.setMinimumSize(txtCapArgs.getPreferredSize());
			row.add(lblCapArgs);
			row.add(Box.createHorizontalStrut(10));
			row.add(txtCapArgs);
			innerPanel.add(row);
			innerPanel.add(Box.createVerticalStrut(5));
			
			row = createRowPanel();		
			txtTCBlastEval = new JTextField(TEXTFIELD_WIDTH);
			txtTCBlastEval.setMaximumSize(txtTCBlastEval.getPreferredSize());
			txtTCBlastEval.setMinimumSize(txtTCBlastEval.getPreferredSize());
			row.add(lblTCBlastEval);
			row.add(Box.createHorizontalStrut(10));
			row.add(txtTCBlastEval);
			innerPanel.add(row);
			innerPanel.add(Box.createVerticalStrut(5));
			
			row = createRowPanel();		
			txtTCBlastParams = new JTextField(TEXTFIELD_WIDTH);
			txtTCBlastParams.setMaximumSize(txtTCBlastParams.getPreferredSize());
			txtTCBlastParams.setMinimumSize(txtTCBlastParams.getPreferredSize());
			row.add(lblTCBlastParams);
			row.add(Box.createHorizontalStrut(10));
			row.add(txtTCBlastParams);
			innerPanel.add(row);
			innerPanel.add(Box.createVerticalStrut(5));
			
			row = createRowPanel();
			txtUserESTSelfBlast = new FileTextField(TEXTFIELD_WIDTH);
			txtUserESTSelfBlast.setMaximumSize(txtUserESTSelfBlast.getPreferredSize());
			txtUserESTSelfBlast.setMinimumSize(txtUserESTSelfBlast.getPreferredSize());
			row.add(lblUserESTSelfBlast);
			row.add(Box.createHorizontalStrut(10));
			row.add(txtUserESTSelfBlast);
			innerPanel.add(row);
			innerPanel.add(Box.createVerticalStrut(10));
			
			row = createRowPanel();
			tblTC = new TCTable();
			tblTC.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
				public void valueChanged(ListSelectionEvent arg0) {
					btnTCRemove.setEnabled(tblTC.getSelectedRow() >= 0);
				}
			});

			tcPane = new JScrollPane(tblTC);
			tcPane.getViewport().setBackground(BGCOLOR);
			
			Dimension tcDim = tcPane.getPreferredSize();
			tcDim.height = 100;
			tcPane.setPreferredSize(tcDim);
			
			JPanel TCTableCtrlPanel = new JPanel();
			TCTableCtrlPanel.setLayout(new BoxLayout(TCTableCtrlPanel, BoxLayout.PAGE_AXIS));
			TCTableCtrlPanel.setAlignmentY(Component.CENTER_ALIGNMENT);
			TCTableCtrlPanel.setBackground(BGCOLOR);
			
			btnTCAdd = new JButton("Add");
			btnTCAdd.setBackground(BGCOLOR);
			btnTCAdd.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					String val = tblTC.getLastRow();
					if(val.length() == 0)
						val = "0 0 0";
					tblTC.addRow(val);
					
					tblTC.setVisible(false);
					tblTC.setVisible(true);
				}
			});
			btnTCRemove = new JButton("Remove");
			btnTCRemove.setBackground(BGCOLOR);
			btnTCRemove.setEnabled(false);
			btnTCRemove.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					tblTC.removeRow(tblTC.getSelectedRow());
					tblTC.getSelectionModel().clearSelection();
					
					tblTC.setVisible(false);
					tblTC.setVisible(true);
				}
			});
			btnTCRemove.setMaximumSize(btnTCRemove.getPreferredSize());
			btnTCRemove.setMinimumSize(btnTCRemove.getPreferredSize());
			btnTCAdd.setMaximumSize(btnTCRemove.getPreferredSize());
			btnTCAdd.setMinimumSize(btnTCRemove.getPreferredSize());
			
			TCTableCtrlPanel.add(btnTCAdd);
			TCTableCtrlPanel.add(Box.createVerticalStrut(10));
			TCTableCtrlPanel.add(btnTCRemove);
			
			row.add(tcPane);
			row.add(Box.createHorizontalStrut(5));
			row.add(TCTableCtrlPanel);
			innerPanel.add(row);
			
			JButton btnResetDefaults = new JButton("Reset To Defaults");
			btnResetDefaults.setBackground(BGCOLOR);
			btnResetDefaults.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent ev) {
					try {
						PaveProps theProps = new PaveProps(PropType.Assem);
						chkSkipAssembly.setSelected(theProps.getProperty("SKIP_ASSEMBLY").equals("1"));
						chkUseTransName.setSelected(theProps.getProperty("USE_TRANS_NAME").equals("1"));
						pnlClique.setValue(theProps.getProperty("CLIQUE"));
						txtCliqueBlastEval.setText(theProps.getProperty("CLIQUE_BLAST_EVAL"));
						txtCliqueBlastParams.setText(theProps.getProperty("CLIQUE_BLAST_PARAMS"));
						pnlSelfJoin.setValue(theProps.getProperty("SELF_JOIN"));
						txtBuryBlastEval.setText(theProps.getProperty("BURY_BLAST_EVAL"));
						txtBuryBlastIdentity.setText(theProps.getProperty("BURY_BLAST_IDENTITY"));
						txtBuryBlastParams.setText(theProps.getProperty("BURY_BLAST_PARAMS"));
						txtCapArgs.setText(theProps.getProperty("CAP_ARGS"));
						txtTCBlastEval.setText(theProps.getProperty("TC_BLAST_EVAL"));
						txtTCBlastParams.setText(theProps.getProperty("TC_BLAST_PARAMS"));
						txtUserESTSelfBlast.setText("");
						
						tblTC.clearAll();
						boolean doneReadingTC = false;
						int TCIdx = 1;
						while(!doneReadingTC) {
							try {
								String val = theProps.getProperty("TC" + TCIdx);
								if(val.length() > 0)
									tblTC.addRow(val);
								else
									doneReadingTC = true;
								TCIdx++;
							}
							catch(Exception e) {
								doneReadingTC = true;
							}
						}
						tblTC.setVisible(false);
						tblTC.setVisible(true);
					}
					catch(Exception e) {
						ErrorReport.prtReport(e, "");
					}
				}
			});
			
			btnKeepAssem = new JButton("Keep");
			btnKeepAssem.setBackground(BGCOLOR);
			btnKeepAssem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					pnlAssemblyOptions.setVisible(false);
					mainPanel.setVisible(true);
	
					curManData.setSkipAssembly(chkSkipAssembly.isSelected());
					curManData.setUseTransNames(chkUseTransName.isSelected());
					curManData.setClique(pnlClique.getValue());
					curManData.setCliqueBlastEval(txtCliqueBlastEval.getText());
					curManData.setCliqueBlastParam(txtCliqueBlastParams.getText());
					curManData.setSelfJoin(pnlSelfJoin.getValue());
					curManData.setBuryBlastEval(txtBuryBlastEval.getText());
					curManData.setBuryBlastIdentity(txtBuryBlastIdentity.getText());
					curManData.setBuryBlastParams(txtBuryBlastParams.getText());
					curManData.setCAPArgs(txtCapArgs.getText());
					curManData.setSelfJoin(pnlSelfJoin.getValue());
					curManData.setTCBlastEval(txtTCBlastEval.getText());
					curManData.setTCBlastParams(txtTCBlastParams.getText());
					curManData.setUserESTSelfBlast(txtUserESTSelfBlast.getText());
					curManData.clearTCs();
					for(int x=0; x<tblTC.getRowCount(); x++)
						curManData.addTC(tblTC.getRawRow(x));
					
					updateUI();
					saveProject();
					nFrameMode = FRAME_MODE_MAIN;
				}
			});
			JButton btnDiscard = new JButton("Discard");
			btnDiscard.setBackground(BGCOLOR);
			btnDiscard.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					pnlAssemblyOptions.setVisible(false);
					mainPanel.setVisible(true);
					
					nFrameMode = FRAME_MODE_MAIN;
				}
			});
			
			JButton btnHelp = new JButton("Help");
			btnHelp.setBackground(HELPCOLOR);
			btnHelp.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					UserPrompt.displayHTMLResourceHelp(getInstance(), 
							"Assembly options help", "html/runSingleTCW/AssemblyOptions.html");
				}
			});
			
			JPanel buttonRow = new JPanel();
			buttonRow.setLayout(new BoxLayout(buttonRow, BoxLayout.LINE_AXIS));
			buttonRow.setAlignmentX(Component.CENTER_ALIGNMENT);
			buttonRow.setBackground(BGCOLOR);
			
			buttonRow.add(btnResetDefaults);
			buttonRow.add(Box.createHorizontalStrut(15));
			buttonRow.add(btnKeepAssem);
			buttonRow.add(Box.createHorizontalStrut(15));
			buttonRow.add(btnDiscard);
			buttonRow.add(Box.createHorizontalStrut(15));
			buttonRow.add(btnHelp);
			
			buttonRow.setMaximumSize(buttonRow.getPreferredSize());
			buttonRow.setMinimumSize(buttonRow.getPreferredSize());
			
			innerPanel.setMaximumSize(innerPanel.getPreferredSize());
			innerPanel.setMinimumSize(innerPanel.getPreferredSize());
			
			pnlAssemblyOptions.add(innerPanel);
			pnlAssemblyOptions.add(Box.createVerticalStrut(10));
			pnlAssemblyOptions.add(buttonRow);
	
			pnlAssemblyOptions.setVisible(false);
		}
		catch(Exception e) {
			ErrorReport.prtReport(e, "Error Building assembly option panel");
		}
	}
	

	/******************************************************************
	 * XXX routines to transfer information to the respective panel before displaying it
	 * and from the respective panel to the data structure for it
	 */
	private void updateAnnoDBEditUI(int index, boolean removeOnDiscard) {
		nCurrentAnnoIndex = index;
		bRemoveAnnoOnDiscard = removeOnDiscard;

		pnlAnnoDBEdit.setLoaded(curManData.getAnnoDBAt(index).isLoaded());
		pnlAnnoDBEdit.setTaxonomy(curManData.getAnnoDBAt(index).getTaxo());
		pnlAnnoDBEdit.setTabularFile(curManData.getAnnoDBAt(index).getTabularFile());
		pnlAnnoDBEdit.setDBfastaFile(curManData.getAnnoDBAt(index).getFastaDB());
		pnlAnnoDBEdit.setSearchPgm(curManData.getAnnoDBAt(index).getSearchPgm());
		pnlAnnoDBEdit.setParams(curManData.getAnnoDBAt(index).getParams());
		pnlAnnoDBEdit.setUnannotated(curManData.getAnnoDBAt(index).getUnannotated());
		pnlAnnoDBEdit.setDate(curManData.getAnnoDBAt(index).getDate());
	}
	
	public void updateAnnoDBUI() {
		curManData.getAnnoDBAt(nCurrentAnnoIndex).setTaxo(pnlAnnoDBEdit.getTaxonomy());
		curManData.getAnnoDBAt(nCurrentAnnoIndex).setTabularFile(pnlAnnoDBEdit.getTabularFile());
		curManData.getAnnoDBAt(nCurrentAnnoIndex).setFastaDB(pnlAnnoDBEdit.getDBfastaFile());
		
		curManData.getAnnoDBAt(nCurrentAnnoIndex).setUnannotated(pnlAnnoDBEdit.getUnannotated());
		curManData.getAnnoDBAt(nCurrentAnnoIndex).setDate(pnlAnnoDBEdit.getDate());
		curManData.getAnnoDBAt(nCurrentAnnoIndex).setSearchPgm(pnlAnnoDBEdit.getSearchPgm());
		curManData.getAnnoDBAt(nCurrentAnnoIndex).setParams(pnlAnnoDBEdit.getParams());
	}
	
	private void updateExpLibEditUI(int index, boolean removeOnDiscard) {
		nCurrentExpLibIndex = index;
		bRemoveExpLibOnDiscard = removeOnDiscard;
		
		pnlExpLibEdit.setEnabled(EditPanel.EXP_LIB_SYMBOLS[0], false);
		pnlExpLibEdit.setValue(EditPanel.EXP_LIB_SYMBOLS[0], curManData.getExpLibraryAt(index).getLibID());
		pnlExpLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[0], curManData.getExpLibraryAt(index).getTitle());
		pnlExpLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[1], curManData.getExpLibraryAt(index).getOrganism());
		pnlExpLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[2], curManData.getExpLibraryAt(index).getCultivar());
		pnlExpLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[3], curManData.getExpLibraryAt(index).getStrain());
		pnlExpLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[4], curManData.getExpLibraryAt(index).getTissue());
		pnlExpLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[5], curManData.getExpLibraryAt(index).getStage());
		pnlExpLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[6], curManData.getExpLibraryAt(index).getTreatment());
	
		pnlExpLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[7], curManData.getExpLibraryAt(index).getYear());
		pnlExpLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[8], curManData.getExpLibraryAt(index).getSource());
	}
	
	public void updateExpLibUI() {
		curManData.getExpLibraryAt(nCurrentExpLibIndex).setLibID((String)pnlExpLibEdit.getValue(EditPanel.EXP_LIB_SYMBOLS[0]));
		curManData.getExpLibraryAt(nCurrentExpLibIndex).setTitle((String)pnlExpLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[0])); 
		curManData.getExpLibraryAt(nCurrentExpLibIndex).setOrganism((String)pnlExpLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[1]));
		curManData.getExpLibraryAt(nCurrentExpLibIndex).setCultivar((String)pnlExpLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[2]));
	    curManData.getExpLibraryAt(nCurrentExpLibIndex).setStrain((String)pnlExpLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[3]));
		curManData.getExpLibraryAt(nCurrentExpLibIndex).setTissue((String)pnlExpLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[4]));
		curManData.getExpLibraryAt(nCurrentExpLibIndex).setStage((String)pnlExpLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[5]));
		curManData.getExpLibraryAt(nCurrentExpLibIndex).setTreatment((String)pnlExpLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[6]));
	
		curManData.getExpLibraryAt(nCurrentExpLibIndex).setYear((String)pnlExpLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[7]));
		curManData.getExpLibraryAt(nCurrentExpLibIndex).setSource((String)pnlExpLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[8]));
	}
	private void updateTransLibEditUI(int index, boolean dbExists) {
		nCurTransLibIndex = index;
		
		pnlTransLibEdit.setValue(EditPanel.TRANS_LIB_SYMBOLS[0], curManData.getTransLibraryAt(index).getTransLibID());
		pnlTransLibEdit.setValue(EditPanel.TRANS_LIB_SYMBOLS[1], curManData.getTransLibraryAt(index).getSeqFile());
		pnlTransLibEdit.setValue(EditPanel.TRANS_LIB_SYMBOLS[2], curManData.getTransLibraryAt(index).getQualFile());
		pnlTransLibEdit.setValue(EditPanel.TRANS_LIB_SYMBOLS[3], curManData.getTransLibraryAt(index).getExpFile());
		pnlTransLibEdit.setValue(EditPanel.TRANS_LIB_SYMBOLS[4], curManData.getTransLibraryAt(index).getExpPrefix());
		pnlTransLibEdit.setValue(EditPanel.TRANS_LIB_SYMBOLS[5], curManData.getTransLibraryAt(index).getFivePrimeSuffix());
		pnlTransLibEdit.setValue(EditPanel.TRANS_LIB_SYMBOLS[6], curManData.getTransLibraryAt(index).getThreePrimeSuffix());
		pnlTransLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[0], curManData.getTransLibraryAt(index).getTitle());
		pnlTransLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[1], curManData.getTransLibraryAt(index).getOrganism());
		pnlTransLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[2], curManData.getTransLibraryAt(index).getCultivar());
		pnlTransLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[3], curManData.getTransLibraryAt(index).getStrain());
		pnlTransLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[4], curManData.getTransLibraryAt(index).getTissue());
		pnlTransLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[5], curManData.getTransLibraryAt(index).getStage());
		pnlTransLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[6], curManData.getTransLibraryAt(index).getTreatment());
	
		pnlTransLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[7], curManData.getTransLibraryAt(index).getYear());
		pnlTransLibEdit.setValue(EditPanel.ATTRIBUTE_SYMBOLS[8], curManData.getTransLibraryAt(index).getSource());
		
		// If add, everything is editable
		// If edit, if the !dbExists, can edit ID but not files (need to make then update right to be all editable); 
		boolean doEdit=true;
		if (!bAddTransLib && !dbExists) doEdit=false;
		pnlTransLibEdit.setEnabled(EditPanel.TRANS_LIB_SYMBOLS[0], doEdit); // ID
		pnlTransLibEdit.setEnabled(EditPanel.TRANS_LIB_SYMBOLS[1], bAddTransLib); // Seqfile 
		pnlTransLibEdit.setEnabled(EditPanel.TRANS_LIB_SYMBOLS[2], bAddTransLib); // qualfile
		pnlTransLibEdit.setEnabled(EditPanel.TRANS_LIB_SYMBOLS[3], bAddTransLib); // countfile
		pnlTransLibEdit.setEnabled(EditPanel.TRANS_LIB_SYMBOLS[4], doEdit); // prefix, not used
		pnlTransLibEdit.setEnabled(EditPanel.TRANS_LIB_SYMBOLS[5], doEdit); // 5'
		pnlTransLibEdit.setEnabled(EditPanel.TRANS_LIB_SYMBOLS[6], doEdit); //3'
	}
	
	public boolean isLibraryLoaded() { 
		if(curManData == null) return false;
		return curManData.isLibraryLoaded();
	}
	
	public boolean transIDValid() {
		String transID = (String)pnlTransLibEdit.getValue(EditPanel.TRANS_LIB_SYMBOLS[0]);
		
		//Check if transID
		for(int x=0; x<curManData.getNumTransLibs(); x++) {
			if(x != nCurTransLibIndex) {
				if(curManData.getTransLibraryAt(x).getTransLibID().equals(transID))
					return false;
			}
		}

		return true;
	}
	
	//Called on Keep from EditTransLibPanel, i.e. a Transcript/Read library has been added
	public boolean updateTransLibUI() {
		boolean valid = true;
		
		String transID = (String)pnlTransLibEdit.getValue(EditPanel.TRANS_LIB_SYMBOLS[0]);		
		String prefix = (String)pnlTransLibEdit.getValue(EditPanel.TRANS_LIB_SYMBOLS[4]);
		curManData.getTransLibraryAt(nCurTransLibIndex).setTransLibID(
				transID);
		curManData.getTransLibraryAt(nCurTransLibIndex).setSeqFile(
				(String)pnlTransLibEdit.getValue(EditPanel.TRANS_LIB_SYMBOLS[1]));
		curManData.getTransLibraryAt(nCurTransLibIndex).setQualFile(
				(String)pnlTransLibEdit.getValue(EditPanel.TRANS_LIB_SYMBOLS[2]));
		curManData.getTransLibraryAt(nCurTransLibIndex).setExpFile(
				(String)pnlTransLibEdit.getValue(EditPanel.TRANS_LIB_SYMBOLS[3]));
		curManData.getTransLibraryAt(nCurTransLibIndex).setExpPrefix(prefix);
		curManData.getTransLibraryAt(nCurTransLibIndex).setFivePrimeSuffix(
				(String)pnlTransLibEdit.getValue(EditPanel.TRANS_LIB_SYMBOLS[5]));
		curManData.getTransLibraryAt(nCurTransLibIndex).setThreePrimeSuffix(
				(String)pnlTransLibEdit.getValue(EditPanel.TRANS_LIB_SYMBOLS[6]));
		
		// The expression level file(s) were just defined, so need to read 
		if(bAddTransLib) { 
            if(curManData.getTransLibraryAt(nCurTransLibIndex).getExpFile().length() > 0) {
                File temp = null;
                if(curManData.getTransLibraryAt(nCurTransLibIndex).getExpFile().startsWith("/"))
                   temp = new File(curManData.getTransLibraryAt(nCurTransLibIndex).getExpFile());
                else
                   temp = new File(LIBDIR + ((String)cmbProjects.getSelectedItem()) + "/" 
                		   		+ curManData.getTransLibraryAt(nCurTransLibIndex).getExpFile());

                String [] expLibs = ManagerData.readExpLevelLibs(null, temp);
                if(expLibs == null) return false;//Error reported parsing file
                
                transID = curManData.getTransLibraryAt(nCurTransLibIndex).getTransLibID();
                prefix = curManData.getTransLibraryAt(nCurTransLibIndex).getExpPrefix();
                for(int x=0; x<expLibs.length; x++) {
                    if(!curManData.addLibToExp(transID, expLibs[x], prefix)) {
	                    			valid = false;
                    }
                }
            }
        }
		else {
			String oldName = pnlTransLibEdit.getOldTransLibID();
			for(int x=0; x<curManData.getNumExpLibs(); x++) {
				if(curManData.getExpLibraryAt(x).getTransID().equals(oldName)) {
					curManData.getExpLibraryAt(x).setTransID(transID);
					curManData.getExpLibraryAt(x).setPrefix(prefix);
				}
			}
	
			for(int x=0; x<curManData.getNumReps(); x++) {
				if(curManData.getRepLibraryAt(x).getTransID().equals(oldName)) {
					curManData.getRepLibraryAt(x).setTransID(transID);
					curManData.getRepLibraryAt(x).setExpPrefix(prefix);
				}
			}
		}
		
		curManData.getTransLibraryAt(nCurTransLibIndex).setTitle(
				(String)pnlTransLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[0]));
		curManData.getTransLibraryAt(nCurTransLibIndex).setOrganism(
				(String)pnlTransLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[1]));
		curManData.getTransLibraryAt(nCurTransLibIndex).setCultivar(
				(String)pnlTransLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[2]));
		curManData.getTransLibraryAt(nCurTransLibIndex).setStrain(
				(String)pnlTransLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[3]));
		curManData.getTransLibraryAt(nCurTransLibIndex).setTissue(
				(String)pnlTransLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[4]));
		curManData.getTransLibraryAt(nCurTransLibIndex).setStage(
				(String)pnlTransLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[5]));
		curManData.getTransLibraryAt(nCurTransLibIndex).setTreatment(
				(String)pnlTransLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[6]));	
		curManData.getTransLibraryAt(nCurTransLibIndex).setYear(
				(String)pnlTransLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[7]));
		curManData.getTransLibraryAt(nCurTransLibIndex).setSource(
				(String)pnlTransLibEdit.getValue(EditPanel.ATTRIBUTE_SYMBOLS[8]));
		
		return valid;
	}
	/*****************************************************************
	 * XXX Database routines
	 */
	public Connection getConnection() {
		try {
			if(!checkMysqlDB(hostsObj.host, curManData.getPAVEDB(), hostsObj.user, hostsObj.pass)) {
				System.err.println("Problem with mySQL");
				return null;
			}
			Class.forName("com.mysql.jdbc.Driver");
			String dbstr = "jdbc:mysql://" + hostsObj.host + "/" + curManData.getPAVEDB();
			Connection con = null; 
		
			con = DriverManager.getConnection(dbstr, hostsObj.user, hostsObj.pass);
				return con;
		}
		catch (Exception e) {
			ErrorReport.reportError(e, "Cannot open database connection");
			return null;
		}
	}
	private static boolean checkMysqlDB(String host, String db, String user, String pass) 
	{
		String dbstr = "jdbc:mysql://" + host + "/" + db;
		Connection con = null; 

		try
		{
			Class.forName("com.mysql.jdbc.Driver");
			con = DriverManager.getConnection(dbstr, user, pass);
			con.close();
			return true;
		} 
		catch (Exception e){	}
		return false;
	}
	
	private boolean isDBLoaded() {
		if (curManData == null) {
			System.err.println("Error: current project is null");
			return false;
		}
		dbExists = checkMysqlDB(hostsObj.host, curManData.getPAVEDB(), hostsObj.user, hostsObj.pass);
		return dbExists;
	}
	
	private boolean isProteinDBLoaded() {
		try {
			if(!checkMysqlDB(hostsObj.host, curManData.getPAVEDB(), hostsObj.user, hostsObj.pass))
				return false;
			
			Class.forName("com.mysql.jdbc.Driver");
			String dbstr = "jdbc:mysql://" + hostsObj.host + "/" + curManData.getPAVEDB();
			Connection con = null; 

			con = DriverManager.getConnection(dbstr, hostsObj.user, hostsObj.pass);
			Statement st = con.createStatement();

			boolean ret=false;
			
	        ResultSet rs = st.executeQuery("show tables like 'assem_msg'");
	        if (!rs.first()) System.err.println("The database has missing tables.");
			rs = st.executeQuery("show columns from  assem_msg where field='peptide'");
			if (rs.first()) ret = true;
			rs.close();
			return ret;
		}
		catch(Exception e) {
			ErrorReport.prtReport(e, "Error checking mySQL database");
		}
		return false;
	}
	
	private void updateAnnoDBLoadStatus() {
		try {
			if(!checkMysqlDB(hostsObj.host, curManData.getPAVEDB(), hostsObj.user, hostsObj.pass))
				return;
			
			Class.forName("com.mysql.jdbc.Driver");
			String dbstr = "jdbc:mysql://" + hostsObj.host + "/" + curManData.getPAVEDB();
			Connection con = DriverManager.getConnection(dbstr, hostsObj.user, hostsObj.pass);
			Statement st = con.createStatement();

			Vector<String> fastaDBs = new Vector<String> ();
			
			for(int x=0; x<curManData.getNumAnnoDBs(); x++) {
				// CAS this was null somehow 1/14/15 -- need to fix
				if (curManData.getAnnoDBAt(x)==null || curManData.getAnnoDBAt(x).getFastaDB()==null) {
					//ErrorReport.die("TCW ERROR: please restart -- it should fix itself");
				}
				else {
					fastaDBs.add(curManData.getAnnoDBAt(x).getFastaDB()); 
					curManData.getAnnoDBAt(x).setLoaded(false);
				}
			}
			// CAS 2May15 at least on MAC, the stored path and sTCW path are not the same.
			// updates the loaded status for the annoDB list, 
			// once the flags are set, italic are used when appropriate
			ResultSet rs = st.executeQuery("SELECT path FROM pja_databases");
			while(rs.next()) {
				String path = rs.getString(1);
				for (int i=0; i<fastaDBs.size(); i++) {
					String db = fastaDBs.get(i);
					if(db.equals(path)) curManData.getAnnoDBAt(i).setLoaded(true);
					else if (db.endsWith(path))  curManData.getAnnoDBAt(i).setLoaded(true);
					else if (path.endsWith(db))  curManData.getAnnoDBAt(i).setLoaded(true);
				}
			}
			rs.close();		
		}
		catch(Exception e) {
			ErrorReport.prtReport(e, "Error getting load status");
		}
	}
	private void removeSelectedAnnotation() {
		try {
			if (!dbExists) {
				System.err.println("Database " + curManData.getPAVEDB() + " does not exist");
			}
			else {
				CoreDBWrapper sqlObj = new CoreDBWrapper(hostsObj.host, curManData.getPAVEDB(), hostsObj.user, hostsObj.pass);
				sqlObj.deleteAnnotation();
			}
		}
		catch(Exception e) {ErrorReport.prtReport(e, "Deleting annotation");}
	}
	private void removeSelectedDatabase() {
		try
		{
			Class.forName("com.mysql.jdbc.Driver");
			String dbstr = "jdbc:mysql://" + hostsObj.host;
			Connection con = null; 
	
			con = DriverManager.getConnection(dbstr, hostsObj.user, hostsObj.pass);
			Statement st = con.createStatement();
				
			ResultSet rset = st.executeQuery("show databases");
			boolean valid = false;
			while(rset.next() && !valid) {
				if(rset.getString(1).equals(curManData.getPAVEDB()))
					valid = true;
			}
			rset.close();
				
			if(valid) {
				st.execute("drop database " + curManData.getPAVEDB());
				System.err.println("Successfully removed " + curManData.getPAVEDB());
			}
			else {
				System.err.println("Database " + curManData.getPAVEDB() + " does not exist");
			}
			con.close();
			curManData.setLibraryLoaded(false);
			for(int x=0; x<curManData.getNumAnnoDBs(); x++)
				curManData.getAnnoDBAt(x).setLoaded(false);
			dbExists=false;
		} 
		catch (Exception e)
		{
			ErrorReport.reportError(e, "Cannot delete database " + curManData.getPAVEDB());
		}
	}
	
	// called on saveProject to pass updated information to the ManagerData
	private void updateProjectData() {
		try {
			if(curManData == null) return;
			
			curManData.setAssemblyID(txtAssemblyID.getText());
			if(!txtPAVEdb.getText().startsWith("sTCW_") && !txtPAVEdb.getText().startsWith("PAVE_")) // CAS 2/13
				txtPAVEdb.setText("sTCW_" + txtPAVEdb.getText());
			curManData.setPAVEDB(txtPAVEdb.getText());
			if(txtNumCPUs.getText().length() > 0)
				curManData.setNumCPUs(Integer.parseInt(txtNumCPUs.getText()));
			else
				curManData.setNumCPUs(1);
			
			curManData.setSkipAssembly(chkSkipAssembly.isSelected());
			curManData.setUseTransNames(chkUseTransName.isEnabled() && chkUseTransName.isSelected());
			
			curManData.clearCountFiles();
			for(int x=0; x<pnlTransLibEdit.getNumCountFiles(); x++) {
				curManData.addNewCountFile(pnlTransLibEdit.getCountFileAt(x), pnlTransLibEdit.getCountHeaderAt(x));
			}
			
		}
		catch(Exception e) {
			ErrorReport.prtReport(e, "Error updating project data");
		}
	}

	/********************************************************
	 * Update library metadata in database
	 * CAS 12/10/14 - was not using the DBConn
	 */
	public void updateTransLibProperties() {
		if(curManData != null && curManData.isLibraryLoaded()) {
			try {
	            DBConn conn = hostsObj.getDBConn(curManData.getPAVEDB());
	            String theStatement = curManData.getTransLib(nCurTransLibIndex);
				conn.executeUpdate(theStatement);
				
				conn.executeUpdate("UPDATE assem_msg SET pja_msg = NULL where AID=1");
				System.out.println("Updated database -- the overview will be regenerated on next viewSingleTCW or Overview");
			}
			catch(Exception e) {
				ErrorReport.prtReport(e, "Error updating translib");
			}
		}
	}
	
	public void updateExpLibProperties() {
		if(curManData != null && curManData.isLibraryLoaded()) {
			try {
				Class.forName("com.mysql.jdbc.Driver");
				String dbstr = "jdbc:mysql://" + hostsObj.host + "/" + curManData.getPAVEDB();
				Connection con = null; 
	
				con = DriverManager.getConnection(dbstr, hostsObj.user, hostsObj.pass);
				Statement st = con.createStatement();
	
				String theStatement = "UPDATE library SET ";
				theStatement += "title = '" + curManData.getExpLibraryAt(nCurrentExpLibIndex).getTitle() + "', ";
				theStatement += "organism = '" + curManData.getExpLibraryAt(nCurrentExpLibIndex).getOrganism() + "', ";
				theStatement += "cultivar = '" + curManData.getExpLibraryAt(nCurrentExpLibIndex).getCultivar() + "', ";
				theStatement += "strain = '" + curManData.getExpLibraryAt(nCurrentExpLibIndex).getStrain() + "', ";
				theStatement += "tissue = '" + curManData.getExpLibraryAt(nCurrentExpLibIndex).getTissue() + "', ";
				theStatement += "stage = '" + curManData.getExpLibraryAt(nCurrentExpLibIndex).getStage() + "', ";
				theStatement += "treatment = '" + curManData.getExpLibraryAt(nCurrentExpLibIndex).getTreatment() + "', ";
				theStatement += "year = '" + curManData.getExpLibraryAt(nCurrentExpLibIndex).getYear() + "', ";
				theStatement += "source = '" + curManData.getExpLibraryAt(nCurrentExpLibIndex).getSource() + "' ";
				theStatement += "WHERE libid = '" + curManData.getExpLibraryAt(nCurrentExpLibIndex).getLibID() + "'";
				
				st.executeUpdate(theStatement);
				
				st.executeUpdate("UPDATE assem_msg SET pja_msg = NULL where AID=1");
			}
			catch(Exception e) {
				ErrorReport.prtReport(e, "Error updating translib");
			}
		}
	}
	
	public void updateAnnoDBTaxonomy() {
		if(curManData != null && curManData.isLibraryLoaded()) {
			try {
				Class.forName("com.mysql.jdbc.Driver");
				String dbstr = "jdbc:mysql://" + hostsObj.host + "/" + curManData.getPAVEDB();
				Connection con = null; 
	
				con = DriverManager.getConnection(dbstr, hostsObj.user, hostsObj.pass);
				Statement st = con.createStatement();
	
				String theStatement = "UPDATE pja_databases SET ";
				theStatement += "taxonomy = '" + curManData.getAnnoDBAt(nCurrentAnnoIndex).getTaxo() + "' ";
				theStatement += "WHERE path = '" + curManData.getAnnoDBAt(nCurrentAnnoIndex).getFastaDB() + "'";
				
				st.executeUpdate(theStatement);
				
				st.executeUpdate("UPDATE assem_msg SET pja_msg = NULL where AID=1");
			}
			catch(Exception e) {
				ErrorReport.prtReport(e, "Error updating taxonomy for annoDB");
			}
		}
	}

	/***************************************************************
	 * XXX other assorted routines and classes
	 * @return
	 */
	public boolean isRemoveAnnoOnDiscard() { return bRemoveAnnoOnDiscard; }
	public void clearCurrentAnnoDB() { 
		curManData.removeAnnoDB(nCurrentAnnoIndex); // CAS 5/18/15 fix the elusive bug? YES!
	}
	public boolean isAddTransLib() { return bAddTransLib;}
	public void clearCurrentTransLib() { curManData.removeTransLib(nCurTransLibIndex); }
	
	public boolean isRemoveExpLibOnDiscard() { return bRemoveExpLibOnDiscard; }
	public void clearCurrentExpLib() { curManData.removeExpLib(nCurrentExpLibIndex); }
	
	/*******************************************************
	 * Called from GenRepsPanel.java 
	 */
	public void generateReps() {
		pnlGenReps.stopEditing();
		
		String [] trans = pnlGenReps.getAllTransLib();
		String [] libs = pnlGenReps.getAllLibid();
		String [] repLibs = pnlGenReps.getAllRepLib();
		String [] prefixes = pnlGenReps.getAllPrefix();
		ManagerData.RepData newRep, oldRep;
		ManagerData.ExpLibData exp;
		
		//Reps have libs[x] set
		curManData.removeAllReps();
		for(int x=0; x<libs.length; x++) {
			if(libs[x].length() > 0) {
				int pos = curManData.addNewRep();
				newRep = curManData.getRepLibraryAt(pos);
				//Now find the expLib source
				boolean done = false;
				for(int y=0; y<curManData.getNumExpLibs() && !done; y++) {
					exp = curManData.getExpLibraryAt(y);			
					if(exp.getTransID().equals(trans[x]) && 
						exp.getLibID().equals(libs[x])) {
						done = true;
						newRep.setLibID(exp.getLibID());
						newRep.setExpPrefix(exp.getPrefix());
						newRep.setTransID(exp.getTransID());
					}
				}
				//New group id typed in
				if(!done) {
					int exPos = curManData.addNewExpLib();
					exp = curManData.getExpLibraryAt(exPos);
					exp.setTransID(trans[x]);
					exp.setPrefix(prefixes[x]);
					exp.setLibID(libs[x]);
					newRep.setLibID(exp.getLibID());
					newRep.setExpPrefix(exp.getPrefix());
					newRep.setTransID(exp.getTransID());
				}
				
				//Set the new id for the rep
				curManData.getRepLibraryAt(curManData.getNumReps() - 1).setRepID(repLibs[x]);
			}
			else { //Was a rep, now back to exp lib
				//Make sure it is not the only one deleted
				boolean found = false;
				for(int i=0; i<curManData.getNumExpLibs() && !found; i++) {
					exp = curManData.getExpLibraryAt(i);
					if(exp.getTransID().equals(trans[x]) && 
							exp.getLibID().equals(repLibs[x]))
						found = true;
				}
				if(!found) {
					int exPos = curManData.addNewExpLib();
					exp = curManData.getExpLibraryAt(exPos);
					exp.setTransID(trans[x]);
					exp.setPrefix(prefixes[x]);
					exp.setLibID(repLibs[x]);
				}
			}
		}
		
		//All reps are set by this point, now time to clean up the explib list
		//Remove explibs that are now reps
		for(int x=0; x<curManData.getNumReps(); x++) {
			oldRep = curManData.getRepLibraryAt(x);
			for(int y=curManData.getNumExpLibs()-1; y>=0; y--) {
				exp = curManData.getExpLibraryAt(y);
				if(exp.getTransID().equals(oldRep.getTransID()) &&
					exp.getLibID().equals(oldRep.getRepID()) &&
						(!oldRep.getLibID().equals(oldRep.getRepID()))) {
					curManData.removeExpLib(y);
				}
			}
		}
		//Set the rep counts for each group
		for(int x=curManData.getNumExpLibs()-1; x>=0; x--) {
			int numReps = 0;
			exp = curManData.getExpLibraryAt(x);
			for(int y=0; y<curManData.getNumReps(); y++) {
				oldRep = curManData.getRepLibraryAt(y);
				if(oldRep.getTransID().equals(exp.getTransID()) &&
						oldRep.getLibID().equals(exp.getLibID()))
					numReps++;
					
			}
			if(numReps > 0)
				exp.setNumReps(numReps);
			else {
				//Determine if unassigned expLib
				boolean found = false;
				for(int i=0; i<libs.length && !found; i++) {
					if(exp.getTransID().equals(trans[i]) && exp.getLibID().equals(repLibs[i]))
						found = true;
				}
				if(!found)
					curManData.removeExpLib(x);
			}
		}
		
		updateUI();
		
		pnlGenReps.setVisible(false);
		mainPanel.setVisible(true);
		saveProject();		
	}
		
	private String [] getLibraryList(boolean first) {
		try {
			
			File dir = new File(LIBDIR);
			if (!dir.exists()) 
			{
			    System.err.println("Creating directory " + LIBDIR);
			    boolean result = dir.mkdir();  
			    if(!result) System.err.println("Error: could not create /" + LIBDIR + " Check permissions"); 
			    File d2 = new File(PROJDIR);
			    if (!d2.exists())
				{
				    System.err.println("Creating directory /" + PROJDIR);
				    result = d2.mkdir();  
				    if(!result) System.err.println("Error: could not create /" + PROJDIR + ". Check permissions"); 
				}
			    return new String [0];
			}
			if (first) System.err.println("Reading projects from directory " + LIBDIR);
		
			Vector<String> dirs = new Vector<String> ();
			String [] files = dir.list();
			for(int x=0; x<files.length; x++) {
				File temp = new File(LIBDIR + files[x]);
				if(temp.exists() && temp.isDirectory() && !temp.isHidden())
					dirs.add(files[x]);
			}
			
			Collections.sort(dirs, String.CASE_INSENSITIVE_ORDER);
			String [] retVal = new String[dirs.size()];
			for(int x=0; x<retVal.length; x++)
				retVal[x] = dirs.get(x);
			
			dirs.clear();
			return retVal;
		}
		catch(Exception e) {return null;}
	}
	
	private static String combineString(String source, String newItem) {
		if(source.length() == 0)
			return newItem;
		return source + ", " + newItem;
	}
	// XXX called from EditTransLibPanel on Keep
	public void updateUI() {
		boolean libLoaded = false;
		boolean projectSelected = (curManData != null);
		boolean isProteinDB = (projectSelected && curManData.isProteinDB());
		boolean hasGO = false;
		
		annoDBTable.resetData();
		expLibraryTable.resetData();
		transLibraryTable.resetData();
		
		if(projectSelected) {
			libLoaded = curManData.isLibraryLoaded();
			
			String assemValue = ""; // stuff added to this, but then never used
			if(curManData.getSkipAssembly())
				assemValue = combineString(assemValue, "Skip Assembly");
			if(curManData.getClique().length() > 0)
				assemValue = combineString(assemValue, "Clique: " + curManData.getClique());
			if(curManData.getCliqueBlastEval().length() > 0)
				assemValue = combineString(assemValue, "Clique Blast Eval: " + curManData.getCliqueBlastEval());
			if(curManData.getCliqueBlastParam().length() > 0)
				assemValue = combineString(assemValue, "Clique Blast Params: " + curManData.getCliqueBlastParam());
			if(curManData.getSelfJoin().length() > 0)
				assemValue = combineString(assemValue, "Self Join: " + curManData.getSelfJoin());
			if(curManData.getBuryBlastEval().length() > 0)
				assemValue = combineString(assemValue, "Bury Blast Eval: " + curManData.getBuryBlastEval());
			if(curManData.getBuryBlastIdentity().length() > 0)
				assemValue = combineString(assemValue, "Bury Blast Identity: " + curManData.getBuryBlastIdentity());
			if(curManData.getBuryBlastParams().length() > 0)
				assemValue = combineString(assemValue, "Bury Blast Params: " + curManData.getBuryBlastParams());
			if(curManData.getCAPArgs().length() > 0)
				assemValue = combineString(assemValue, "CAP args: " + curManData.getCAPArgs());
			if(curManData.getTCBlastEval().length() > 0)
				assemValue = combineString(assemValue, "TC Blast Eval: " + curManData.getTCBlastEval());
			if(curManData.getTCBlastParams().length() > 0)
				assemValue = combineString(assemValue, "TC Blast Params: " + curManData.getTCBlastParams());
			if(curManData.getUserESTSelfBlast().length() > 0)
				assemValue = combineString(assemValue, "User EST Self Blast: " + curManData.getUserESTSelfBlast());
			for(int x=0; x<curManData.getNumTCs(); x++) {
				assemValue = combineString(assemValue, "TC" + (x+1) + ": " + curManData.getTCAt(x));
			}
			
			String annoValue = ""; 
			if(curManData.getUnitransType() > 0)
				annoValue = "Unitrans Type " + curManData.getUnitransType();
			if(curManData.getUnitransSelfBlast() != null && curManData.getUnitransSelfBlast().length() == 0)
				annoValue = combineString(annoValue, "Nucleotide Self Blast");
			else if(curManData.getUnitransSelfBlast() != null)
				annoValue = combineString(annoValue, "Self blast using " + curManData.getUnitransSelfBlast());
			if(curManData.getUnitransSelfBlastParams().length() > 0)
				annoValue = combineString(annoValue, "Self Blast Args: " + curManData.getUnitransSelfBlastParams());			
			if(curManData.getUnitransTSelfBlast() != null && curManData.getUnitransTSelfBlast().length() == 0)
				annoValue = combineString(annoValue, "Translated Nucleotide Self Blast");
			else if(curManData.getUnitransTSelfBlast() != null)
				annoValue = combineString(annoValue, "T Self blast using " + curManData.getUnitransTSelfBlast());
			if(curManData.getUnitransTSelfBlastParams().length() > 0)
				annoValue = combineString(annoValue, "T Self Blast Args: " + curManData.getUnitransTSelfBlastParams());
			if(curManData.getPairsLimit() > 0)
				annoValue = combineString(annoValue, "Pairs limit = " + curManData.getPairsLimit());
			
			txtAssemblyID.setText(curManData.getAssemblyID());
			txtPAVEdb.setText(curManData.getPAVEDB());
			
			if(curManData.getNumCPUs() > 0)
				txtNumCPUs.setText(curManData.getNumCPUs() + "");
			
			// CAS 2/9/15 something is making an new annoDB sometimes not show, remove the !=null
			//       from loop test incase that is why (cannot reproduce)
			// CAS 5/2/15 add 3rd column
			for(int x=0; x<curManData.getNumAnnoDBs(); x++) {
				if (curManData.getAnnoDBAt(x) != null) {
					String [] temp = new String[3];
					temp[0] = curManData.getAnnoDBAt(x).getTaxo();
					temp[1] = curManData.getAnnoDBAt(x).getTabularFile();
					if (temp[1].contains("/"))
						temp[1] = temp[1].substring(temp[1].lastIndexOf("/"));
					else if (temp[1].equals("")) {
						// TODO if TCW_select, call DoBlast with getFastaDB to determine
						temp[1] = curManData.getAnnoDBAt(x).getSearchPgm();
					}
					temp[2] = curManData.getAnnoDBAt(x).getFastaDB();
					if (temp[2].contains("/"))
						temp[2] = temp[2].substring(temp[2].lastIndexOf("/"));
					
					annoDBTable.addRow(curManData.getAnnoDBAt(x).isSelected(), 
							curManData.getAnnoDBAt(x).isLoaded(), temp);
				}
			}
			annoDBTable.setVisible(false);
			annoDBTable.setVisible(true);
			
			for(int x=0; x<curManData.getNumTransLibs() && curManData.getTransLibraryAt(x) != null; x++) {
				String [] temp = new String[2];
				temp[0] = curManData.getTransLibraryAt(x).getTransLibID();
				temp[1] = curManData.getTransLibraryAt(x).getTitle();
				
				if(curManData.getTransLibraryAt(x).getExpFile().length() > 0)
					transLibraryTable.addRow(true, true, temp);
				else
					transLibraryTable.addRow(false, false, temp);
			}
			transLibraryTable.setVisible(false);
			transLibraryTable.setVisible(true);

			// adds content to the Transcrip Read Count table
			for(int x=0; x<curManData.getNumExpLibs(); x++) {
				String [] temp = new String[4]; 
				temp[0] = curManData.getExpLibraryAt(x).getTransID();
				temp[1] = curManData.getExpLibraryAt(x).getLibID();
				temp[2] = curManData.getExpLibraryAt(x).getTitle(); 
				temp[3] = curManData.getExpLibraryAt(x).getNumReps() + ""; 
				expLibraryTable.addRow(true, false, temp);
			}
			expLibraryTable.setVisible(false);
			expLibraryTable.setVisible(true);
			
			if(curManData.getGODB().length() > 0)
			{
				lblGODB.setText("GO database: " + curManData.getGODB());
				hasGO = true;
			}
			else
				lblGODB.setText("GO database: none");
			
			chkSkipAssembly.setSelected(curManData.getSkipAssembly());
			chkUseTransName.setSelected(curManData.getUseTransNames());
		} // end if (projectSelected)
		else {
			lblGODB.setText("");
			txtAssemblyID.setText("");
			txtPAVEdb.setText("");
			cmbHost.setSelectedIndex(0);
		}
				
		txtAssemblyID.setEnabled(!bBusy && !libLoaded && projectSelected);
		txtPAVEdb.setEnabled(!bBusy && !libLoaded && projectSelected);
		cmbHost.setEnabled(!bBusy && projectSelected); 
		txtNumCPUs.setEnabled(!bBusy && projectSelected);
		btnGetState.setEnabled(!bBusy && projectSelected);
		btnSaveProject.setEnabled(!bBusy && projectSelected);
		btnRemoveProject.setEnabled(!bBusy && projectSelected);
		
		transLibraryTable.setEnabled(!bBusy && projectSelected);
		btnAddTransLib.setEnabled(!bBusy && projectSelected && !libLoaded);
		btnEditTransLib.setEnabled(!bBusy && projectSelected && transLibraryTable.getSelectedRowCount() > 0);
		btnRemoveTransLib.setEnabled(!bBusy && projectSelected && transLibraryTable.getSelectedRowCount() > 0 && !libLoaded);
		
		expLibraryTable.setEnabled(!bBusy && projectSelected);
		btnEditExpLib.setEnabled(!bBusy  && projectSelected && expLibraryTable.getSelectedRowCount() > 0);
		btnDefRep.setEnabled(!bBusy && projectSelected && (expLibraryTable.getRowCount() > 0) && !libLoaded);
		btnExecLoadLib.setEnabled(!bBusy && projectSelected);
		
		boolean selected = chkSkipAssembly.isSelected();
		chkSkipAssembly.setEnabled(!bBusy && projectSelected);
		btnAssemOptions.setEnabled(!selected && projectSelected);
		chkUseTransName.setEnabled(selected && projectSelected);
		btnExecAssem.setEnabled(!bBusy && projectSelected && libLoaded);
		
		annoDBTable.setEnabled(!bBusy && projectSelected);
		btnAddAnnoDB.setEnabled(!bBusy && projectSelected);
		btnEditAnnoDB.setEnabled(!bBusy && projectSelected && annoDBTable.getSelectedRowCount() > 0);
		btnRemoveAnnoDB.setEnabled(!bBusy && projectSelected && annoDBTable.getSelectedRowCount() > 0);	
		btnMoveUpAnnoDB.setEnabled(!bBusy && projectSelected && annoDBTable.getSelectedRowCount() > 0);	
		btnMoveDownAnnoDB.setEnabled(!bBusy && projectSelected && annoDBTable.getSelectedRowCount() > 0);	
		
		sPaneAnnoDB.setEnabled(!bBusy && projectSelected);
		btnEditAnnoOptions.setEnabled(!bBusy && projectSelected);
		btnExecAnno.setEnabled(!bBusy && projectSelected && libLoaded);
		btnUpdateGO.setEnabled(!bBusy && projectSelected && libLoaded && hasGO);
		
		btnRunViewPAVE.setEnabled(!bBusy && projectSelected && libLoaded);
		btnRunDE.setEnabled(!bBusy && projectSelected && libLoaded);
		btnAddRemark.setEnabled(!bBusy && projectSelected);
		btnImportAnnot.setEnabled(!bBusy && projectSelected);
		
		chkTSelfBlast.setEnabled(!isProteinDB);
		txtTSelfBlast.setEnabled(!isProteinDB);
		txtTSelfBlastArgs.setEnabled(!isProteinDB);
		tSelfBlastArgLbl.setEnabled(!isProteinDB);
		tSelfBlastExistLbl.setEnabled(!isProteinDB);
	}
	
	private static boolean isFilenameValid(String file) {
	    File f = new File(file);
	    try {
	       f.getCanonicalPath();
	       return file.indexOf('/') < 0;
	    }
	    catch (Exception e) {
	       return false;
	    }
	  }
	
	private ManagerFrame getInstance() { return this; }
	
	public ManagerData getManData() { return curManData;}
	private ManagerData curManData = null;
	
	//Panels for the frame
	private JPanel pnlProject = null;
	private JPanel pnlExpLib = null;
	private JPanel pnlTransLib = null;
	private JPanel pnlAnnoDB = null;
	private JPanel pnlGeneral = null;
	private JPanel pnlAssemblyOptions = null;
	private JPanel pnlAnnoDBOptions = null;
	
	private EditAnnoPanel pnlAnnoDBEdit = null;
	private EditTransLibPanel pnlTransLibEdit = null;
	private EditPanel pnlExpLibEdit = null;
	private GenRepsPanel pnlGenReps = null;
	private AddRemarkPanel pnlRemark = null;
	
	private JPanel mainPanel = null;
	private JScrollPane sPane = null;
	
	//Project controls
	private ButtonComboBox cmbProjects = null;
	private JButton btnAddProject = null;
	private JButton btnSaveProject = null;
	private JButton btnRemoveProject = null;
	private JButton btnHelp = null;
	private JButton btnGetAllState = null;
	private JButton btnGetState = null;
	
	//Exp Library controls
	private ManagerTable expLibraryTable = null;
	private JScrollPane sPaneExpLibrary = null;
	private JButton btnEditExpLib = null;
	private JButton btnDefRep = null;
	
	//Trans Library controls
	private ManagerTable transLibraryTable = null;
	private JScrollPane sPaneTransLibrary = null;
	private JButton btnAddTransLib = null;
	private JButton btnEditTransLib = null;
	private JButton btnRemoveTransLib = null;
	
	private JButton btnAssemOptions = null;
	private ButtonComboBox cmbAnnoUnitransType = null;
	
	private JButton btnExecLoadLib = null;
	private JButton btnExecAssem = null;
	private JButton btnExecAnno = null;
	private JButton btnRunViewPAVE = null;
	private JButton btnRunDE = null;
	private JButton btnImportAnnot = null;
	private JButton btnAddRemark = null;
	private JButton btnUpdateGO = null;

	private JLabel lblGODB = null;
	
	//AnnoDB controls
	private ManagerTable annoDBTable = null;
	private JScrollPane sPaneAnnoDB = null;
	private JButton btnAddAnnoDB = null;
	private JButton btnEditAnnoDB = null;
	private JButton btnRemoveAnnoDB = null;	
	private JButton btnMoveUpAnnoDB = null;
	private JButton btnMoveDownAnnoDB = null;
	private JButton btnEditAnnoOptions = null;
	
	//General controls
	private JTextField txtAssemblyID = null;
	private JTextField txtPAVEdb = null;
	private ButtonComboBox cmbHost = null; 
	private JTextField txtNumCPUs = null;
	
	//Assembly controls
	private JLabel lblClique 			= null;
	private JLabel lblCliqueBlastEval 	= null;
	private JLabel lblCliqueBlastParams = null;
	private JLabel lblSelfJoin	 		= null;
	private JLabel lblBuryBlastEval 	= null;
	private JLabel lblBuryBlastIdentity = null;
	private JLabel lblBuryBlastParams 	= null;
	private JLabel lblCapArgs 			= null;
	private JLabel lblTCBlastEval		= null;
	private JLabel lblTCBlastParams		= null;
	private JLabel lblUserESTSelfBlast  = null; 

	private JCheckBox chkSkipAssembly = null;
	private JCheckBox chkUseTransName = null;
	private MultiIntPanel pnlClique = null;
	private JTextField txtCliqueBlastEval = null;
	private JTextField txtCliqueBlastParams = null;
	private MultiIntPanel pnlSelfJoin = null;
	private JTextField txtBuryBlastEval = null;
	private JTextField txtBuryBlastIdentity = null;
	private JTextField txtBuryBlastParams = null;
	private JTextField txtCapArgs = null;
	private JTextField txtTCBlastEval = null;
	private JTextField txtTCBlastParams = null;
	private FileTextField txtUserESTSelfBlast = null;
	private JScrollPane tcPane = null;
	private TCTable tblTC = null;
	private JButton btnTCAdd = null;
	private JButton btnTCRemove = null;
	private JButton btnKeepAssem = null;
	private boolean bAddTransLib = false;
	
	//Anno controls
	private JTextArea txtDefaultBlastArgs = null;
	private JCheckBox chkSelfBlast = null;
	private FileTextField txtSelfBlast = null;
	private JTextArea txtSelfBlastArgs = null;
	private JCheckBox chkTSelfBlast = null;
	private FileTextField txtTSelfBlast = null;
	private JTextArea txtTSelfBlastArgs = null;
	private JLabel tSelfBlastArgLbl = null;
	private JLabel tSelfBlastExistLbl = null;
	private JTextField txtPairsLimit = null;
	private ButtonComboBox cmbGODB = null;
	
	private boolean dbExists=false;
	//Disable UI if working inthe background
	private boolean bBusy = false;
	
	//AnnoDB Edit
	private int nCurrentAnnoIndex = -1;
	private boolean bRemoveAnnoOnDiscard = false; 
	
	//Exp Library controls
	private int nCurrentExpLibIndex = -1;
	private boolean bRemoveExpLibOnDiscard = false;
	
	//Read Library controls
	private int nCurTransLibIndex = -1;
	private boolean bRemoveTransLibOnDiscard = false;
	
	private Vector<String> theHosts = null;
	
	private int nFrameMode = FRAME_MODE_MAIN;
	
	/***************************************************
	 * called by createAnnoDBOptionsPanel and createAssemlbyOptionPanel
	 */
	private class FileTextField extends JPanel {
		private static final long serialVersionUID = 6670096855895700182L;
		
		public FileTextField(int size) {
			setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
			setAlignmentX(Component.LEFT_ALIGNMENT);
			setBackground(BGCOLOR);
			
			txtValue = new JTextField(size);
			Dimension dTxt = txtValue.getPreferredSize(); 
			txtValue.setMaximumSize(dTxt);
			txtValue.setMinimumSize(dTxt);
			
			btnFindFile = new JButton("...");
			btnFindFile.setBackground(BGCOLOR);
			Dimension dBtn = new Dimension();
			dBtn.width = btnFindFile.getPreferredSize().width;
			dBtn.height = dTxt.height;
			
			btnFindFile.setMaximumSize(dBtn);
			btnFindFile.setMinimumSize(dBtn);
			btnFindFile.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent arg0) {
					try {
						JFileChooser fc = new JFileChooser();
						fc.setCurrentDirectory(getProjPath());

						if(fc.showOpenDialog(getInstance()) == JFileChooser.APPROVE_OPTION) {
							txtValue.setText(fc.getSelectedFile().getPath());
						}
					}
					catch(Exception e) {
						ErrorReport.prtReport(e, "Error finding file");
					}
					
				}});
			
			add(txtValue);
			add(btnFindFile);
		}
		
		public void addCaretListener(CaretListener l) { txtValue.addCaretListener(l); }
		
		public void setEnabled(boolean enabled) { 
			txtValue.setEnabled(enabled);
			btnFindFile.setEnabled(enabled);
		}
		
		public void setText(String text) { txtValue.setText(text); }
		public String getText() { return txtValue.getText(); }
		
		private JTextField txtValue = null;
		private JButton btnFindFile = null;
	}
	
	public class OutputHandler extends Thread
	{
	    InputStream is;
	    
	    public OutputHandler(InputStream is)
	    {
	        this.is = is;
	    }
	    
	    public void Stop() {
		    	try {
			    	if(is != null) is.close();
		    	}
		    	catch(Exception e) {	}
		}
	    
	    public void run()
	    {
	        try
	        {
				int c;
				while((c = is.read()) != -1) {
					System.err.print((char)c);
					System.err.flush();
				}
	        } catch (Exception e) {}
	    }
	}
	
	public class InputHandler extends Thread
	{
	    boolean keepRunning = true;
	    BufferedReader inRead;
	    InputStreamReader isr;
	    BufferedWriter osw;
	    
	    public InputHandler(OutputStream os) {
	        isr = new InputStreamReader(System.in);
	        osw = new BufferedWriter(new OutputStreamWriter(os));
	    }
	    
	    public void Stop() {
	    		keepRunning = false;
	    }
	    
	    public void run()
	    {
	        try {
		        	while (keepRunning)
		        	{
		        		if (isr.ready())
		        		{
		        			int c = isr.read();
		        			osw.write(c);
		        			osw.flush();
		        		}
		        		Thread.sleep(100);
		        	}
		        	osw.close();
		        	inRead.close();
	        } 
	        catch (Exception e) {}
	    }
	}
	
	/****************************************************
	 * used in assembly panel
	 */
	public class MultiIntPanel extends JPanel {
		private static final long serialVersionUID = -5168685239942043613L;
		
		public MultiIntPanel(String [] labels) {
			setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
			setBackground(BGCOLOR);
			
			theLabels = new JLabel[labels.length];
			theFields = new JTextField[labels.length];
			for(int x=0; x<theLabels.length; x++) {
				JPanel section = new JPanel();
				section.setLayout(new BoxLayout(section, BoxLayout.PAGE_AXIS));
				section.setBackground(BGCOLOR);
				
				theLabels[x] = new JLabel(labels[x]);
				theLabels[x].setAlignmentX(Component.CENTER_ALIGNMENT);
				theFields[x] = new JTextField(NUM_FIELD_WIDTH);
				theFields[x].setAlignmentX(Component.CENTER_ALIGNMENT);
				theFields[x].setMaximumSize(theFields[x].getPreferredSize());
				theFields[x].setMinimumSize(theFields[x].getPreferredSize());

				section.add(theLabels[x]);
				section.add(theFields[x]);
				
				add(section);
				if(x < theLabels.length - 1)
					add(Box.createHorizontalStrut(10));
			}
		}
		
		public boolean isEmptyVals() {
			if(theFields == null) return true;
			boolean empty = true;
			for(int x=0; x<theFields.length && empty; x++) {
				if(theFields[x].getText().length() > 0) {
					empty = false;
				}
			}
			return empty;
		}
	
		public void setChangeListener(CaretListener l) {
			for(int x=0; x<theFields.length; x++) {
				theFields[x].addCaretListener(l);
			}
		}
		
		public boolean isValidVals() {
			if(isEmptyVals()) return true;
			
			boolean retVal = true;
			
			for(int x=0; x<theFields.length && retVal; x++) {
				if(theFields[x].getText().length() > 0) {
					try {
						Integer.parseInt(theFields[x].getText());
					}
					catch(Exception e) {
						retVal = false;
					}
				}
				else
					retVal = false;
			}
			
			return retVal;
		}
	
		public void setValue(String value) {
			if(value.length() == 0) {
				for(int x=0; x<theFields.length; x++)
					theFields[x].setText("");
			}
			else {
				String [] vals = value.split(" ");
				for(int x=0; x<vals.length; x++) {
					theFields[x].setText(vals[x]);
				}
			}
		}
		
		public String getValue() {
			if(isEmptyVals()) return "";
			
			String retVal = "";
			for(int x=0; x<theFields.length; x++) {
				int val = 0;
				if(theFields[x].getText().length() > 0)
					val = Integer.parseInt(theFields[x].getText());
				retVal += val + " ";
			}
			return retVal.trim();
		}
		
		public void setEnabled(boolean enabled) {
			for(int x=0; x<theFields.length; x++)
				theFields[x].setEnabled(enabled);
			for(int x=0; x<theLabels.length; x++)
				theLabels[x].setEnabled(enabled);
		}
		
		private JTextField [] theFields = null;
		private JLabel [] theLabels = null;
	}	
}
